|
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; |