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