src/HOL/Tools/Predicate_Compile/predicate_compile_data.ML
changeset 35324 c9f428269b38
parent 35267 8dfd816713c6
child 35404 de56579ae229
equal deleted inserted replaced
35309:997aa3a3e4bb 35324:c9f428269b38
     4 Book-keeping datastructure for the predicate compiler.
     4 Book-keeping datastructure for the predicate compiler.
     5 *)
     5 *)
     6 
     6 
     7 signature PREDICATE_COMPILE_DATA =
     7 signature PREDICATE_COMPILE_DATA =
     8 sig
     8 sig
     9   type specification_table;
     9   val ignore_consts : string list -> theory -> theory
    10   (*val make_const_spec_table : Predicate_Compile_Aux.options -> theory -> specification_table*)
    10   val keep_functions : string list -> theory -> theory
    11   val get_specification : theory -> term -> thm list
    11   val keep_function : theory -> string -> bool
       
    12   val processed_specs : theory -> string -> (string * thm list) list option
       
    13   val store_processed_specs : (string * (string * thm list) list) -> theory -> theory
       
    14   
       
    15   val get_specification : Predicate_Compile_Aux.options -> theory -> term -> thm list
    12   val obtain_specification_graph :
    16   val obtain_specification_graph :
    13     Predicate_Compile_Aux.options -> theory -> term -> thm list TermGraph.T
    17     Predicate_Compile_Aux.options -> theory -> term -> thm list TermGraph.T
       
    18     
       
    19   val present_graph : thm list TermGraph.T -> unit
    14   val normalize_equation : theory -> thm -> thm
    20   val normalize_equation : theory -> thm -> thm
    15 end;
    21 end;
    16 
    22 
    17 structure Predicate_Compile_Data : PREDICATE_COMPILE_DATA =
    23 structure Predicate_Compile_Data : PREDICATE_COMPILE_DATA =
    18 struct
    24 struct
    20 open Predicate_Compile_Aux;
    26 open Predicate_Compile_Aux;
    21 
    27 
    22 structure Data = Theory_Data
    28 structure Data = Theory_Data
    23 (
    29 (
    24   type T =
    30   type T =
    25     {const_spec_table : thm list Symtab.table};
    31     {ignore_consts : unit Symtab.table,
       
    32      keep_functions : unit Symtab.table,
       
    33      processed_specs : ((string * thm list) list) Symtab.table};
    26   val empty =
    34   val empty =
    27     {const_spec_table = Symtab.empty};
    35     {ignore_consts = Symtab.empty,
       
    36      keep_functions = Symtab.empty,
       
    37      processed_specs =  Symtab.empty};
    28   val extend = I;
    38   val extend = I;
    29   fun merge
    39   fun merge
    30     ({const_spec_table = const_spec_table1},
    40     ({ignore_consts = c1, keep_functions = k1, processed_specs = s1},
    31      {const_spec_table = const_spec_table2}) =
    41      {ignore_consts = c2, keep_functions = k2, processed_specs = s2}) =
    32      {const_spec_table = Symtab.merge (K true) (const_spec_table1, const_spec_table2)}
    42      {ignore_consts = Symtab.merge (K true) (c1, c2),
       
    43       keep_functions = Symtab.merge (K true) (k1, k2),
       
    44       processed_specs = Symtab.merge (K true) (s1, s2)}
    33 );
    45 );
    34 
    46 
    35 fun mk_data c = {const_spec_table = c}
    47 
    36 fun map_data f {const_spec_table = c} = mk_data (f c)
    48 
    37 
    49 fun mk_data (c, k, s) = {ignore_consts = c, keep_functions = k, processed_specs = s}
    38 type specification_table = thm list Symtab.table
    50 fun map_data f {ignore_consts = c, keep_functions = k, processed_specs = s} = mk_data (f (c, k, s))
       
    51 
       
    52 fun ignore_consts cs = Data.map (map_data (apfst3 (fold (fn c => Symtab.insert (op =) (c, ())) cs)))
       
    53 
       
    54 fun keep_functions cs = Data.map (map_data (apsnd3 (fold (fn c => Symtab.insert (op =) (c, ())) cs)))
       
    55 
       
    56 fun keep_function thy = Symtab.defined (#keep_functions (Data.get thy))
       
    57 
       
    58 fun processed_specs thy = Symtab.lookup (#processed_specs (Data.get thy))
       
    59 
       
    60 fun store_processed_specs (constname, specs) =
       
    61   Data.map (map_data (aptrd3 (Symtab.update_new (constname, specs))))
       
    62 (* *)
       
    63 
    39 
    64 
    40 fun defining_term_of_introrule_term t =
    65 fun defining_term_of_introrule_term t =
    41   let
    66   let
    42     val _ $ u = Logic.strip_imp_concl t
    67     val _ $ u = Logic.strip_imp_concl t
    43   in fst (strip_comb u) end
    68   in fst (strip_comb u) end
   118       in ((Free (x, T), HOLogic.mk_ptuple paths T (map Free xTs)), nctxt') end
   143       in ((Free (x, T), HOLogic.mk_ptuple paths T (map Free xTs)), nctxt') end
   119     val (rewr, _) = fold_map mk_tuple_rewrites frees nctxt 
   144     val (rewr, _) = fold_map mk_tuple_rewrites frees nctxt 
   120     val t' = Pattern.rewrite_term thy rewr [] t
   145     val t' = Pattern.rewrite_term thy rewr [] t
   121     val tac = Skip_Proof.cheat_tac thy
   146     val tac = Skip_Proof.cheat_tac thy
   122     val th'' = Goal.prove ctxt (Term.add_free_names t' []) [] t' (fn _ => tac)
   147     val th'' = Goal.prove ctxt (Term.add_free_names t' []) [] t' (fn _ => tac)
   123     val th''' = LocalDefs.unfold ctxt [@{thm split_conv}] th''
   148     val th''' = LocalDefs.unfold ctxt [@{thm split_conv}, @{thm fst_conv}, @{thm snd_conv}] th''
   124   in
   149   in
   125     th'''
   150     th'''
   126   end;
   151   end;
   127 
   152 
   128 fun normalize_equation thy th =
       
   129   mk_meta_equation th
       
   130   |> Predicate_Compile_Set.unfold_set_notation
       
   131   |> full_fun_cong_expand
       
   132   |> split_all_pairs thy
       
   133   |> tap check_equation_format
       
   134 
   153 
   135 fun inline_equations thy th =
   154 fun inline_equations thy th =
   136   let
   155   let
   137     val inline_defs = Predicate_Compile_Inline_Defs.get (ProofContext.init thy)
   156     val inline_defs = Predicate_Compile_Inline_Defs.get (ProofContext.init thy)
   138     val th' = (Simplifier.full_simplify (HOL_basic_ss addsimps inline_defs)) th
   157     val th' = (Simplifier.full_simplify (HOL_basic_ss addsimps inline_defs)) th
   141        ^ "with " ^ (commas (map ((Syntax.string_of_term_global thy) o prop_of) inline_defs))
   160        ^ "with " ^ (commas (map ((Syntax.string_of_term_global thy) o prop_of) inline_defs))
   142        ^" to " ^ (Syntax.string_of_term_global thy (prop_of th')))*)
   161        ^" to " ^ (Syntax.string_of_term_global thy (prop_of th')))*)
   143   in
   162   in
   144     th'
   163     th'
   145   end
   164   end
   146 (*
   165 
   147 fun store_thm_in_table options ignore thy th=
   166 fun normalize_equation thy th =
   148   let
   167   mk_meta_equation th
   149     val th = th
   168   |> full_fun_cong_expand
   150       |> inline_equations options thy
   169   |> split_all_pairs thy
   151       |> Predicate_Compile_Set.unfold_set_notation
   170   |> tap check_equation_format
   152       |> AxClass.unoverload thy
   171   |> inline_equations thy
   153     val (const, th) =
   172 
   154       if is_equationlike th then
   173 fun normalize_intros thy th =
   155         let
   174   split_all_pairs thy th
   156           val eq = normalize_equation thy th
   175   |> inline_equations thy
   157         in
   176 
   158           (defining_const_of_equation eq, eq)
   177 fun normalize thy th =
   159         end
   178   if is_equationlike th then
   160       else if is_introlike th then (defining_const_of_introrule th, th)
   179     normalize_equation thy th
   161       else error "store_thm: unexpected definition format"
   180   else
   162   in
   181     normalize_intros thy th
   163     if ignore const then I else Symtab.cons_list (const, th)
   182 
   164   end
   183 fun get_specification options thy t =
   165 
   184   let
   166 fun make_const_spec_table options thy =
   185     (*val (c, T) = dest_Const t
   167   let
   186     val t = Const (AxClass.unoverload_const thy (c, T), T)*)
   168     fun store ignore f =
   187     val _ = if show_steps options then
   169       fold (store_thm_in_table options ignore thy)
   188         tracing ("getting specification of " ^ Syntax.string_of_term_global thy t ^
   170         (map (Thm.transfer thy) (f ))
   189           " with type " ^ Syntax.string_of_typ_global thy (fastype_of t))
   171     val table = Symtab.empty
   190       else ()
   172       |> store (K false) Predicate_Compile_Alternative_Defs.get
       
   173     val ignore = Symtab.defined table
       
   174   in
       
   175     table
       
   176     |> store ignore (fn ctxt => maps
       
   177       else [])
       
   178         
       
   179     |> store ignore Nitpick_Simps.get
       
   180     |> store ignore Nitpick_Intros.get
       
   181   end
       
   182 
       
   183 fun get_specification table constname =
       
   184   case Symtab.lookup table constname of
       
   185     SOME thms => thms                  
       
   186   | NONE => error ("get_specification: lookup of constant " ^ quote constname ^ " failed")
       
   187 *)
       
   188 
       
   189 fun get_specification thy t =
       
   190   Output.cond_timeit true "get_specification" (fn () =>
       
   191   let
       
   192     val ctxt = ProofContext.init thy
   191     val ctxt = ProofContext.init thy
   193     fun filtering th =
   192     fun filtering th =
   194       if is_equationlike th andalso
   193       if is_equationlike th andalso
   195         defining_const_of_equation (normalize_equation thy th) = (fst (dest_Const t)) then
   194         defining_const_of_equation (normalize_equation thy th) = fst (dest_Const t) then
   196         SOME (normalize_equation thy th)
   195         SOME (normalize_equation thy th)
   197       else
   196       else
   198         if is_introlike th andalso defining_term_of_introrule th = t then
   197         if is_introlike th andalso defining_term_of_introrule th = t then
   199           SOME th
   198           SOME th
   200         else
   199         else
   201           NONE
   200           NONE
   202   in
   201     val spec = case map_filter filtering (map (normalize thy o Thm.transfer thy) (Predicate_Compile_Alternative_Defs.get ctxt))
   203     case map_filter filtering (map (Thm.transfer thy) (Predicate_Compile_Alternative_Defs.get ctxt))
       
   204      of [] => (case Spec_Rules.retrieve ctxt t
   202      of [] => (case Spec_Rules.retrieve ctxt t
   205        of [] => rev (map_filter filtering (map (Thm.transfer thy) (Nitpick_Intros.get ctxt)))
   203        of [] => (case rev ( 
       
   204          (map_filter filtering (map (normalize_intros thy o Thm.transfer thy)
       
   205            (Nitpick_Intros.get ctxt))))
       
   206          of [] => error ("No specification for " ^ (Syntax.string_of_term_global thy t))
       
   207           | ths => ths)
   206        | ((_, (_, ths)) :: _) => map (normalize_equation thy o Thm.transfer thy) ths)
   208        | ((_, (_, ths)) :: _) => map (normalize_equation thy o Thm.transfer thy) ths)
   207      | ths => rev ths
   209      | ths => rev ths
   208   end)
   210     val _ =
       
   211       if show_intermediate_results options then
       
   212         Output.tracing (commas (map (Display.string_of_thm_global thy) spec))
       
   213       else ()
       
   214   in
       
   215     spec
       
   216   end
   209 
   217 
   210 val logic_operator_names =
   218 val logic_operator_names =
   211   [@{const_name "=="}, 
   219   [@{const_name "=="}, 
   212    @{const_name "==>"},
   220    @{const_name "==>"},
   213    @{const_name "Trueprop"},
   221    @{const_name "Trueprop"},
   214    @{const_name "Not"},
   222    @{const_name "Not"},
   215    @{const_name "op ="},
   223    @{const_name "op ="},
   216    @{const_name "op -->"},
   224    @{const_name "op -->"},
   217    @{const_name "All"},
   225    @{const_name "All"},
   218    @{const_name "Ex"}, 
   226    @{const_name "Ex"}, 
   219    @{const_name "op &"}]
   227    @{const_name "op &"},
       
   228    @{const_name "op |"}]
   220 
   229 
   221 fun special_cases (c, T) = member (op =) [
   230 fun special_cases (c, T) = member (op =) [
   222   @{const_name Product_Type.Unity},
   231   @{const_name Product_Type.Unity},
   223   @{const_name False},
   232   @{const_name False},
   224   @{const_name Suc}, @{const_name Nat.zero_nat_inst.zero_nat},
   233   @{const_name Suc}, @{const_name Nat.zero_nat_inst.zero_nat},
   231   @{const_name number_nat_inst.number_of_nat},
   240   @{const_name number_nat_inst.number_of_nat},
   232   @{const_name Int.Bit0},
   241   @{const_name Int.Bit0},
   233   @{const_name Int.Bit1},
   242   @{const_name Int.Bit1},
   234   @{const_name Int.Pls},
   243   @{const_name Int.Pls},
   235   @{const_name Int.zero_int_inst.zero_int},
   244   @{const_name Int.zero_int_inst.zero_int},
   236   @{const_name List.filter}] c
   245   @{const_name List.filter},
       
   246   @{const_name HOL.If},
       
   247   @{const_name Groups.minus}
       
   248   ] c
       
   249 
   237 
   250 
   238 fun print_specification options thy constname specs = 
   251 fun print_specification options thy constname specs = 
   239   if show_intermediate_results options then
   252   if show_intermediate_results options then
   240     tracing ("Specification of " ^ constname ^ ":\n" ^
   253     tracing ("Specification of " ^ constname ^ ":\n" ^
   241       cat_lines (map (Display.string_of_thm_global thy) specs))
   254       cat_lines (map (Display.string_of_thm_global thy) specs))
   252       |> filter_out is_datatype_constructor
   265       |> filter_out is_datatype_constructor
   253       |> filter_out is_nondefining_const
   266       |> filter_out is_nondefining_const
   254       |> filter_out has_code_pred_intros
   267       |> filter_out has_code_pred_intros
   255       |> filter_out case_consts
   268       |> filter_out case_consts
   256       |> filter_out special_cases
   269       |> filter_out special_cases
       
   270       |> filter_out (fn (c, _) => Symtab.defined (#ignore_consts (Data.get thy)) c)
       
   271       |> map (fn (c, _) => (c, Sign.the_const_constraint thy c))
   257       |> map Const
   272       |> map Const
   258       (*
   273       (*
   259       |> filter is_defining_constname*)
   274       |> filter is_defining_constname*)
   260     fun extend t =
   275     fun extend t =
   261       let
   276       let
   262         val specs = get_specification thy t
   277         val specs = get_specification options thy t
   263           |> map (inline_equations thy)
       
   264           (*|> Predicate_Compile_Set.unfold_set_notation*)
   278           (*|> Predicate_Compile_Set.unfold_set_notation*)
   265         (*val _ = print_specification options thy constname specs*)
   279         (*val _ = print_specification options thy constname specs*)
   266       in (specs, defiants_of specs) end;
   280       in (specs, defiants_of specs) end;
   267   in
   281   in
   268     TermGraph.extend extend t TermGraph.empty
   282     TermGraph.extend extend t TermGraph.empty
   269   end;
   283   end;
   270   
   284 
       
   285 
       
   286 fun present_graph gr =
       
   287   let
       
   288     fun eq_cname (Const (c1, _), Const (c2, _)) = (c1 = c2)
       
   289     fun string_of_const (Const (c, _)) = c
       
   290       | string_of_const _ = error "string_of_const: unexpected term"
       
   291     val constss = TermGraph.strong_conn gr;
       
   292     val mapping = Termtab.empty |> fold (fn consts => fold (fn const =>
       
   293       Termtab.update (const, consts)) consts) constss;
       
   294     fun succs consts = consts
       
   295       |> maps (TermGraph.imm_succs gr)
       
   296       |> subtract eq_cname consts
       
   297       |> map (the o Termtab.lookup mapping)
       
   298       |> distinct (eq_list eq_cname);
       
   299     val conn = [] |> fold (fn consts => cons (consts, succs consts)) constss;
       
   300     
       
   301     fun namify consts = map string_of_const consts
       
   302       |> commas;
       
   303     val prgr = map (fn (consts, constss) =>
       
   304       { name = namify consts, ID = namify consts, dir = "", unfold = true,
       
   305         path = "", parents = map namify constss }) conn;
       
   306   in Present.display_graph prgr end;
       
   307 
   271 
   308 
   272 end;
   309 end;