src/HOL/Tools/Predicate_Compile/pred_compile_data.ML
changeset 32668 b2de45007537
child 32669 462b1dd67a58
equal deleted inserted replaced
32667:09546e654222 32668:b2de45007537
       
     1 (* Author: Lukas Bulwahn, TU Muenchen
       
     2 
       
     3 Book-keeping datastructure for the predicate compiler
       
     4 
       
     5 *)
       
     6 signature PRED_COMPILE_DATA =
       
     7 sig
       
     8   type specification_table;
       
     9   val make_const_spec_table : theory -> specification_table
       
    10   val get_specification :  specification_table -> string -> thm list
       
    11   val obtain_specification_graph : specification_table -> string -> thm list Graph.T
       
    12   val normalize_equation : theory -> thm -> thm
       
    13 end;
       
    14 
       
    15 structure Pred_Compile_Data : PRED_COMPILE_DATA =
       
    16 struct
       
    17 
       
    18 open Predicate_Compile_Aux;
       
    19 
       
    20 structure Data = TheoryDataFun
       
    21 (
       
    22   type T =
       
    23     {const_spec_table : thm list Symtab.table};
       
    24   val empty =
       
    25     {const_spec_table = Symtab.empty};
       
    26   val copy = I;
       
    27   val extend = I;
       
    28   fun merge _
       
    29     ({const_spec_table = const_spec_table1},
       
    30      {const_spec_table = const_spec_table2}) =
       
    31      {const_spec_table = Symtab.merge (K true) (const_spec_table1, const_spec_table2)}
       
    32 );
       
    33 
       
    34 fun mk_data c = {const_spec_table = c}
       
    35 fun map_data f {const_spec_table = c} = mk_data (f c)
       
    36 
       
    37 type specification_table = thm list Symtab.table
       
    38 
       
    39 fun defining_const_of_introrule_term t =
       
    40   let
       
    41     val _ $ u = Logic.strip_imp_concl t
       
    42     val (pred, all_args) = strip_comb u
       
    43   in case pred of
       
    44     Const (c, T) => c
       
    45     | _ => raise TERM ("defining_const_of_introrule_term failed: Not a constant", [t])
       
    46   end
       
    47 
       
    48 val defining_const_of_introrule = defining_const_of_introrule_term o prop_of
       
    49 
       
    50 (*TODO*)
       
    51 fun is_introlike_term t = true
       
    52 
       
    53 val is_introlike = is_introlike_term o prop_of
       
    54 
       
    55 fun check_equation_format_term (t as (Const ("==", _) $ u $ v)) =
       
    56   (case strip_comb u of
       
    57     (Const (c, T), args) =>
       
    58       if (length (binder_types T) = length args) then
       
    59         true
       
    60       else
       
    61         raise TERM ("check_equation_format_term failed: Number of arguments mismatch", [t])
       
    62   | _ => raise TERM ("check_equation_format_term failed: Not a constant", [t]))
       
    63   | check_equation_format_term t =
       
    64     raise TERM ("check_equation_format_term failed: Not an equation", [t])
       
    65 
       
    66 val check_equation_format = check_equation_format_term o prop_of
       
    67 
       
    68 fun defining_const_of_equation_term (t as (Const ("==", _) $ u $ v)) =
       
    69   (case fst (strip_comb u) of
       
    70     Const (c, _) => c
       
    71   | _ => raise TERM ("defining_const_of_equation_term failed: Not a constant", [t]))
       
    72   | defining_const_of_equation_term t =
       
    73     raise TERM ("defining_const_of_equation_term failed: Not an equation", [t])
       
    74 
       
    75 val defining_const_of_equation = defining_const_of_equation_term o prop_of
       
    76 
       
    77 (* Normalizing equations *)
       
    78 
       
    79 fun mk_meta_equation th =
       
    80   case prop_of th of
       
    81     Const ("Trueprop", _) $ (Const ("op =", _) $ _ $ _) => th RS @{thm eq_reflection}
       
    82   | _ => th
       
    83 
       
    84 fun full_fun_cong_expand th =
       
    85   let
       
    86     val (f, args) = strip_comb (fst (Logic.dest_equals (prop_of th)))
       
    87     val i = length (binder_types (fastype_of f)) - length args
       
    88   in funpow i (fn th => th RS @{thm meta_fun_cong}) th end;
       
    89 
       
    90 fun declare_names s xs ctxt =
       
    91   let
       
    92     val res = Name.names ctxt s xs
       
    93   in (res, fold Name.declare (map fst res) ctxt) end
       
    94   
       
    95 fun split_all_pairs thy th =
       
    96   let
       
    97     val ctxt = ProofContext.init thy
       
    98     val ((_, [th']), ctxt') = Variable.import true [th] ctxt
       
    99     val t = prop_of th'
       
   100     val frees = Term.add_frees t [] 
       
   101     val freenames = Term.add_free_names t []
       
   102     val nctxt = Name.make_context freenames
       
   103     fun mk_tuple_rewrites (x, T) nctxt =
       
   104       let
       
   105         val Ts = HOLogic.flatten_tupleT T
       
   106         val (xTs, nctxt') = declare_names x Ts nctxt
       
   107         val paths = HOLogic.flat_tupleT_paths T
       
   108       in ((Free (x, T), HOLogic.mk_ptuple paths T (map Free xTs)), nctxt') end
       
   109     val (rewr, _) = fold_map mk_tuple_rewrites frees nctxt 
       
   110     val t' = Pattern.rewrite_term thy rewr [] t
       
   111     val tac = SkipProof.cheat_tac thy
       
   112     val th'' = Goal.prove ctxt (Term.add_free_names t' []) [] t' (fn {...} => tac)
       
   113     val th''' = LocalDefs.unfold ctxt [@{thm split_conv}] th''
       
   114   in
       
   115     th'''
       
   116   end;
       
   117 
       
   118 fun normalize_equation thy th =
       
   119   mk_meta_equation th
       
   120 	|> Pred_Compile_Set.unfold_set_notation
       
   121   |> full_fun_cong_expand
       
   122   |> split_all_pairs thy
       
   123   |> tap check_equation_format
       
   124 
       
   125 fun inline_equations thy th = Conv.fconv_rule (Simplifier.rewrite
       
   126 ((Simplifier.theory_context thy Simplifier.empty_ss) addsimps (Predicate_Compile_Inline_Defs.get (ProofContext.init thy)))) th
       
   127 
       
   128 fun store_thm_in_table ignore_consts thy th=
       
   129   let
       
   130     val th = AxClass.unoverload thy th
       
   131       |> inline_equations thy
       
   132     val (const, th) =
       
   133       if is_equationlike th then
       
   134         let
       
   135           val _ = priority "Normalizing definition..."
       
   136           val eq = normalize_equation thy th
       
   137         in
       
   138           (defining_const_of_equation eq, eq)
       
   139         end
       
   140       else if (is_introlike th) then
       
   141         let val th = Pred_Compile_Set.unfold_set_notation th
       
   142         in (defining_const_of_introrule th, th) end
       
   143       else error "store_thm: unexpected definition format"
       
   144   in
       
   145     if not (member (op =) ignore_consts const) then
       
   146       Symtab.cons_list (const, th)
       
   147     else I
       
   148   end
       
   149 
       
   150 (*
       
   151 fun make_const_spec_table_warning thy =
       
   152   fold
       
   153     (fn th => fn thy => case try (store_thm th) thy of
       
   154       SOME thy => thy
       
   155     | NONE => (warning ("store_thm fails for " ^ Display.string_of_thm_global thy th) ; thy))
       
   156       (Predicate_Compile_Preproc_Const_Defs.get (ProofContext.init thy)) thy
       
   157 
       
   158 fun make_const_spec_table thy =
       
   159   fold store_thm (Predicate_Compile_Preproc_Const_Defs.get (ProofContext.init thy)) thy
       
   160   |> (fn thy => fold store_thm (Nitpick_Const_Simps.get (ProofContext.init thy)) thy)
       
   161 *)
       
   162 fun make_const_spec_table thy =
       
   163   let
       
   164     fun store ignore_const f = fold (store_thm_in_table ignore_const thy) (map (Thm.transfer thy) (f (ProofContext.init thy)))
       
   165     val table = Symtab.empty
       
   166       |> store [] Predicate_Compile_Alternative_Defs.get
       
   167     val ignore_consts = Symtab.keys table
       
   168   in
       
   169     table   
       
   170     |> store ignore_consts Predicate_Compile_Preproc_Const_Defs.get
       
   171     |> store ignore_consts Nitpick_Const_Simps.get
       
   172     |> store ignore_consts Nitpick_Ind_Intros.get
       
   173   end
       
   174   (*
       
   175 fun get_specification thy constname =
       
   176   case Symtab.lookup (#const_spec_table (Data.get thy)) constname of
       
   177     SOME thms => thms
       
   178   | NONE => error ("get_specification: lookup of constant " ^ quote constname ^ " failed")
       
   179   *)
       
   180 fun get_specification table constname =
       
   181   case Symtab.lookup table constname of
       
   182   SOME thms =>
       
   183     let
       
   184       val _ = tracing ("Looking up specification of " ^ constname ^ ": "
       
   185         ^ (commas (map Display.string_of_thm_without_context thms)))
       
   186     in thms end
       
   187   | NONE => error ("get_specification: lookup of constant " ^ quote constname ^ " failed")
       
   188 
       
   189 val logic_operator_names =
       
   190   [@{const_name "=="}, @{const_name "op ="}, @{const_name "op -->"}, @{const_name "All"}, @{const_name "op &"}]
       
   191 
       
   192 val special_cases = member (op =) [@{const_name "Suc"}, @{const_name Nat.zero_nat_inst.zero_nat},
       
   193     @{const_name Nat.one_nat_inst.one_nat},
       
   194 @{const_name "HOL.ord_class.less"}, @{const_name "HOL.ord_class.less_eq"}, @{const_name "HOL.zero_class.zero"},
       
   195 @{const_name "HOL.one_class.one"},  @{const_name HOL.plus_class.plus},
       
   196 @{const_name "Nat.nat.nat_case"}, @{const_name "List.list.list_case"}, @{const_name Nat.ord_nat_inst.less_eq_nat}]
       
   197 
       
   198 fun obtain_specification_graph table constname =
       
   199   let
       
   200     fun is_nondefining_constname c = member (op =) logic_operator_names c
       
   201     val is_defining_constname = member (op =) (Symtab.keys table)
       
   202     fun defiants_of specs =
       
   203       fold (Term.add_const_names o prop_of) specs []
       
   204       |> filter is_defining_constname
       
   205       |> filter_out special_cases
       
   206     fun extend constname =
       
   207       let
       
   208         val specs = get_specification table constname
       
   209       in (specs, defiants_of specs) end;
       
   210   in
       
   211     Graph.extend extend constname Graph.empty
       
   212   end;
       
   213   
       
   214   
       
   215 end;