1 (* Title: Tools/Compute_Oracle/Linker.ML |
1 (* Title: Tools/Compute_Oracle/Linker.ML |
2 ID: $$ |
2 ID: $Id$ |
3 Author: Steven Obua |
3 Author: Steven Obua |
4 |
4 |
5 Linker.ML solves the problem that the computing oracle does not instantiate polymorphic rules. |
5 Linker.ML solves the problem that the computing oracle does not |
6 By going through the PCompute interface, all possible instantiations are resolved by compiling new programs, if necessary. |
6 instantiate polymorphic rules. By going through the PCompute interface, |
7 The obvious disadvantage of this approach is that in the worst case for each new term to be rewritten, a new program may be compiled. |
7 all possible instantiations are resolved by compiling new programs, if |
|
8 necessary. The obvious disadvantage of this approach is that in the |
|
9 worst case for each new term to be rewritten, a new program may be |
|
10 compiled. |
8 *) |
11 *) |
9 |
12 |
10 (* |
13 (* |
11 Given constants/frees c_1::t_1, c_2::t_2, ...., c_n::t_n, |
14 Given constants/frees c_1::t_1, c_2::t_2, ...., c_n::t_n, |
12 and constants/frees d_1::d_1, d_2::s_2, ..., d_m::s_m |
15 and constants/frees d_1::d_1, d_2::s_2, ..., d_m::s_m |
13 |
16 |
14 Find all substitutions S such that |
17 Find all substitutions S such that |
15 a) the domain of S is tvars (t_1, ..., t_n) |
18 a) the domain of S is tvars (t_1, ..., t_n) |
16 b) there are indices i_1, ..., i_k, and j_1, ..., j_k with |
19 b) there are indices i_1, ..., i_k, and j_1, ..., j_k with |
17 1. S (c_i_1::t_i_1) = d_j_1::s_j_1, ..., S (c_i_k::t_i_k) = d_j_k::s_j_k |
20 1. S (c_i_1::t_i_1) = d_j_1::s_j_1, ..., S (c_i_k::t_i_k) = d_j_k::s_j_k |
18 2. tvars (t_i_1, ..., t_i_k) = tvars (t_1, ..., t_n) |
21 2. tvars (t_i_1, ..., t_i_k) = tvars (t_1, ..., t_n) |
19 *) |
22 *) |
20 signature LINKER = |
23 signature LINKER = |
21 sig |
24 sig |
22 exception Link of string |
25 exception Link of string |
23 |
26 |
24 datatype constant = Constant of bool * string * typ |
27 datatype constant = Constant of bool * string * typ |
25 val constant_of : term -> constant |
28 val constant_of : term -> constant |
26 |
29 |
27 type instances |
30 type instances |
28 type subst = Type.tyenv |
31 type subst = Type.tyenv |
29 |
32 |
30 val empty : constant list -> instances |
33 val empty : constant list -> instances |
31 val typ_of_constant : constant -> typ |
34 val typ_of_constant : constant -> typ |
32 val add_instances : Type.tsig -> instances -> constant list -> subst list * instances |
35 val add_instances : theory -> instances -> constant list -> subst list * instances |
33 val substs_of : instances -> subst list |
36 val substs_of : instances -> subst list |
34 val is_polymorphic : constant -> bool |
37 val is_polymorphic : constant -> bool |
35 val distinct_constants : constant list -> constant list |
38 val distinct_constants : constant list -> constant list |
36 val collect_consts : term list -> constant list |
39 val collect_consts : term list -> constant list |
37 end |
40 end |
77 | substtab_unions [c] = c |
80 | substtab_unions [c] = c |
78 | substtab_unions (c::cs) = substtab_union c (substtab_unions cs) |
81 | substtab_unions (c::cs) = substtab_union c (substtab_unions cs) |
79 |
82 |
80 datatype instances = Instances of unit ConsttabModTy.table * Type.tyenv Consttab.table Consttab.table * constant list list * unit Substtab.table |
83 datatype instances = Instances of unit ConsttabModTy.table * Type.tyenv Consttab.table Consttab.table * constant list list * unit Substtab.table |
81 |
84 |
82 fun is_polymorphic (Constant (_, _, ty)) = not (null (typ_tvars ty)) |
85 fun is_polymorphic (Constant (_, _, ty)) = not (null (typ_tvars ty)) |
83 |
86 |
84 fun distinct_constants cs = |
87 fun distinct_constants cs = |
85 Consttab.keys (fold (fn c => Consttab.update (c, ())) cs Consttab.empty) |
88 Consttab.keys (fold (fn c => Consttab.update (c, ())) cs Consttab.empty) |
86 |
89 |
87 fun empty cs = |
90 fun empty cs = |
88 let |
91 let |
89 val cs = distinct_constants (filter is_polymorphic cs) |
92 val cs = distinct_constants (filter is_polymorphic cs) |
90 val old_cs = cs |
93 val old_cs = cs |
91 (* fun collect_tvars ty tab = fold (fn v => fn tab => Typtab.update (TVar v, ()) tab) (typ_tvars ty) tab |
94 (* fun collect_tvars ty tab = fold (fn v => fn tab => Typtab.update (TVar v, ()) tab) (typ_tvars ty) tab |
92 val tvars_count = length (Typtab.keys (fold (fn c => fn tab => collect_tvars (typ_of_constant c) tab) cs Typtab.empty)) |
95 val tvars_count = length (Typtab.keys (fold (fn c => fn tab => collect_tvars (typ_of_constant c) tab) cs Typtab.empty)) |
93 fun tvars_of ty = collect_tvars ty Typtab.empty |
96 fun tvars_of ty = collect_tvars ty Typtab.empty |
94 val cs = map (fn c => (c, tvars_of (typ_of_constant c))) cs |
97 val cs = map (fn c => (c, tvars_of (typ_of_constant c))) cs |
95 |
98 |
96 fun tyunion A B = |
99 fun tyunion A B = |
97 Typtab.fold |
100 Typtab.fold |
98 (fn (v,()) => fn tab => Typtab.update (v, case Typtab.lookup tab v of NONE => 1 | SOME n => n+1) tab) |
101 (fn (v,()) => fn tab => Typtab.update (v, case Typtab.lookup tab v of NONE => 1 | SOME n => n+1) tab) |
99 A B |
102 A B |
100 |
103 |
101 fun is_essential A B = |
104 fun is_essential A B = |
102 Typtab.fold |
105 Typtab.fold |
103 (fn (v, ()) => fn essential => essential orelse (case Typtab.lookup B v of NONE => raise Link "is_essential" | SOME n => n=1)) |
106 (fn (v, ()) => fn essential => essential orelse (case Typtab.lookup B v of NONE => raise Link "is_essential" | SOME n => n=1)) |
104 A false |
107 A false |
105 |
108 |
106 fun add_minimal (c', tvs') (tvs, cs) = |
109 fun add_minimal (c', tvs') (tvs, cs) = |
107 let |
110 let |
108 val tvs = tyunion tvs' tvs |
111 val tvs = tyunion tvs' tvs |
109 val cs = (c', tvs')::cs |
112 val cs = (c', tvs')::cs |
110 in |
113 in |
111 if forall (fn (c',tvs') => is_essential tvs' tvs) cs then |
114 if forall (fn (c',tvs') => is_essential tvs' tvs) cs then |
112 SOME (tvs, cs) |
115 SOME (tvs, cs) |
113 else |
116 else |
114 NONE |
117 NONE |
115 end |
118 end |
116 |
119 |
117 fun is_spanning (tvs, _) = (length (Typtab.keys tvs) = tvars_count) |
120 fun is_spanning (tvs, _) = (length (Typtab.keys tvs) = tvars_count) |
118 |
121 |
119 fun generate_minimal_subsets subsets [] = subsets |
122 fun generate_minimal_subsets subsets [] = subsets |
120 | generate_minimal_subsets subsets (c::cs) = |
123 | generate_minimal_subsets subsets (c::cs) = |
121 let |
124 let |
122 val subsets' = map_filter (add_minimal c) subsets |
125 val subsets' = map_filter (add_minimal c) subsets |
123 in |
126 in |
124 generate_minimal_subsets (subsets@subsets') cs |
127 generate_minimal_subsets (subsets@subsets') cs |
125 end*) |
128 end*) |
126 |
129 |
127 val minimal_subsets = [old_cs] (*map (fn (tvs, cs) => map fst cs) (filter is_spanning (generate_minimal_subsets [(Typtab.empty, [])] cs))*) |
130 val minimal_subsets = [old_cs] (*map (fn (tvs, cs) => map fst cs) (filter is_spanning (generate_minimal_subsets [(Typtab.empty, [])] cs))*) |
128 |
131 |
129 val constants = Consttab.keys (fold (fold (fn c => Consttab.update (c, ()))) minimal_subsets Consttab.empty) |
132 val constants = Consttab.keys (fold (fold (fn c => Consttab.update (c, ()))) minimal_subsets Consttab.empty) |
130 |
133 |
131 in |
134 in |
132 Instances ( |
135 Instances ( |
133 fold (fn c => fn tab => ConsttabModTy.update (c, ()) tab) constants ConsttabModTy.empty, |
136 fold (fn c => fn tab => ConsttabModTy.update (c, ()) tab) constants ConsttabModTy.empty, |
134 Consttab.make (map (fn c => (c, Consttab.empty : Type.tyenv Consttab.table)) constants), |
137 Consttab.make (map (fn c => (c, Consttab.empty : Type.tyenv Consttab.table)) constants), |
135 minimal_subsets, Substtab.empty) |
138 minimal_subsets, Substtab.empty) |
136 end |
139 end |
137 |
140 |
138 local |
141 local |
139 fun calc ctab substtab [] = substtab |
142 fun calc ctab substtab [] = substtab |
140 | calc ctab substtab (c::cs) = |
143 | calc ctab substtab (c::cs) = |
141 let |
144 let |
142 val csubsts = map snd (Consttab.dest (the (Consttab.lookup ctab c))) |
145 val csubsts = map snd (Consttab.dest (the (Consttab.lookup ctab c))) |
143 fun merge_substs substtab subst = |
146 fun merge_substs substtab subst = |
144 Substtab.fold (fn (s,_) => |
147 Substtab.fold (fn (s,_) => |
145 fn tab => |
148 fn tab => |
146 (case merge_subst subst s of NONE => tab | SOME s => Substtab.update (s, ()) tab)) |
149 (case merge_subst subst s of NONE => tab | SOME s => Substtab.update (s, ()) tab)) |
147 substtab Substtab.empty |
150 substtab Substtab.empty |
148 val substtab = substtab_unions (map (merge_substs substtab) csubsts) |
151 val substtab = substtab_unions (map (merge_substs substtab) csubsts) |
149 in |
152 in |
150 calc ctab substtab cs |
153 calc ctab substtab cs |
151 end |
154 end |
152 in |
155 in |
153 fun calc_substs ctab (cs:constant list) = calc ctab (Substtab.update (empty_subst, ()) Substtab.empty) cs |
156 fun calc_substs ctab (cs:constant list) = calc ctab (Substtab.update (empty_subst, ()) Substtab.empty) cs |
154 end |
157 end |
155 |
158 |
156 fun add_instances tsig (Instances (cfilter, ctab,minsets,substs)) cs = |
159 fun add_instances thy (Instances (cfilter, ctab,minsets,substs)) cs = |
157 let |
160 let |
158 (* val _ = writeln (makestring ("add_instances: ", length_cs, length cs, length (Consttab.keys ctab)))*) |
161 (* val _ = writeln (makestring ("add_instances: ", length_cs, length cs, length (Consttab.keys ctab)))*) |
159 fun calc_instantiations (constant as Constant (free, name, ty)) instantiations = |
162 fun calc_instantiations (constant as Constant (free, name, ty)) instantiations = |
160 Consttab.fold (fn (constant' as Constant (free', name', ty'), insttab) => |
163 Consttab.fold (fn (constant' as Constant (free', name', ty'), insttab) => |
161 fn instantiations => |
164 fn instantiations => |
162 if free <> free' orelse name <> name' then |
165 if free <> free' orelse name <> name' then |
163 instantiations |
166 instantiations |
164 else case Consttab.lookup insttab constant of |
167 else case Consttab.lookup insttab constant of |
165 SOME _ => instantiations |
168 SOME _ => instantiations |
166 | NONE => ((constant', (constant, Type.typ_match tsig (ty', ty) empty_subst))::instantiations |
169 | NONE => ((constant', (constant, Sign.typ_match thy (ty', ty) empty_subst))::instantiations |
167 handle TYPE_MATCH => instantiations)) |
170 handle TYPE_MATCH => instantiations)) |
168 ctab instantiations |
171 ctab instantiations |
169 val instantiations = fold calc_instantiations cs [] |
172 val instantiations = fold calc_instantiations cs [] |
170 (*val _ = writeln ("instantiations = "^(makestring (length instantiations)))*) |
173 (*val _ = writeln ("instantiations = "^(makestring (length instantiations)))*) |
171 fun update_ctab (constant', entry) ctab = |
174 fun update_ctab (constant', entry) ctab = |
172 (case Consttab.lookup ctab constant' of |
175 (case Consttab.lookup ctab constant' of |
173 NONE => raise Link "internal error: update_ctab" |
176 NONE => raise Link "internal error: update_ctab" |
174 | SOME tab => Consttab.update (constant', Consttab.update entry tab) ctab) |
177 | SOME tab => Consttab.update (constant', Consttab.update entry tab) ctab) |
175 val ctab = fold update_ctab instantiations ctab |
178 val ctab = fold update_ctab instantiations ctab |
176 val new_substs = fold (fn minset => fn substs => substtab_union (calc_substs ctab minset) substs) |
179 val new_substs = fold (fn minset => fn substs => substtab_union (calc_substs ctab minset) substs) |
177 minsets Substtab.empty |
180 minsets Substtab.empty |
178 val (added_substs, substs) = |
181 val (added_substs, substs) = |
179 Substtab.fold (fn (ns, _) => |
182 Substtab.fold (fn (ns, _) => |
180 fn (added, substtab) => |
183 fn (added, substtab) => |
181 (case Substtab.lookup substs ns of |
184 (case Substtab.lookup substs ns of |
182 NONE => (ns::added, Substtab.update (ns, ()) substtab) |
185 NONE => (ns::added, Substtab.update (ns, ()) substtab) |
183 | SOME () => (added, substtab))) |
186 | SOME () => (added, substtab))) |
184 new_substs ([], substs) |
187 new_substs ([], substs) |
185 in |
188 in |
186 (added_substs, Instances (cfilter, ctab, minsets, substs)) |
189 (added_substs, Instances (cfilter, ctab, minsets, substs)) |
187 end |
190 end |
188 |
191 |
189 |
192 |
190 fun substs_of (Instances (_,_,_,substs)) = Substtab.keys substs |
193 fun substs_of (Instances (_,_,_,substs)) = Substtab.keys substs |
191 |
194 |
192 local |
195 local |
193 fun get_thm thmname = PureThy.get_thm (theory "Main") (Name thmname) |
196 fun get_thm thmname = PureThy.get_thm (theory "Main") (Name thmname) |
194 val eq_th = get_thm "HOL.eq_reflection" |
197 val eq_th = get_thm "HOL.eq_reflection" |
195 in |
198 in |
196 fun eq_to_meta th = (eq_th OF [th] handle _ => th) |
199 fun eq_to_meta th = (eq_th OF [th] handle _ => th) |
197 end |
200 end |
198 |
201 |
199 |
202 |
200 local |
203 local |
201 |
204 |
202 fun collect (Var x) tab = tab |
205 fun collect (Var x) tab = tab |
203 | collect (Bound _) tab = tab |
206 | collect (Bound _) tab = tab |
204 | collect (a $ b) tab = collect b (collect a tab) |
207 | collect (a $ b) tab = collect b (collect a tab) |
238 | collect_consts (Bound _) = [] |
241 | collect_consts (Bound _) = [] |
239 | collect_consts (a $ b) = (collect_consts a)@(collect_consts b) |
242 | collect_consts (a $ b) = (collect_consts a)@(collect_consts b) |
240 | collect_consts (Abs (_, _, body)) = collect_consts body |
243 | collect_consts (Abs (_, _, body)) = collect_consts body |
241 | collect_consts t = [Linker.constant_of t]*) |
244 | collect_consts t = [Linker.constant_of t]*) |
242 |
245 |
243 fun collect_consts_of_thm th = |
246 fun collect_consts_of_thm th = |
244 let |
247 let |
245 val th = prop_of th |
248 val th = prop_of th |
246 val (prems, th) = (Logic.strip_imp_prems th, Logic.strip_imp_concl th) |
249 val (prems, th) = (Logic.strip_imp_prems th, Logic.strip_imp_concl th) |
247 val (left, right) = Logic.dest_equals th |
250 val (left, right) = Logic.dest_equals th |
248 in |
251 in |
249 (Linker.collect_consts [left], Linker.collect_consts (right::prems)) |
252 (Linker.collect_consts [left], Linker.collect_consts (right::prems)) |
250 end |
253 end |
251 |
254 |
252 fun create_theorem th = |
255 fun create_theorem th = |
253 let |
256 let |
254 val (left, right) = collect_consts_of_thm th |
257 val (left, right) = collect_consts_of_thm th |
255 val polycs = filter Linker.is_polymorphic left |
258 val polycs = filter Linker.is_polymorphic left |
256 val tytab = fold (fn p => fn tab => fold (fn n => fn tab => Typtab.update (TVar n, ()) tab) (typ_tvars (Linker.typ_of_constant p)) tab) polycs Typtab.empty |
259 val tytab = fold (fn p => fn tab => fold (fn n => fn tab => Typtab.update (TVar n, ()) tab) (typ_tvars (Linker.typ_of_constant p)) tab) polycs Typtab.empty |
257 fun check_const (c::cs) cs' = |
260 fun check_const (c::cs) cs' = |
258 let |
261 let |
259 val tvars = typ_tvars (Linker.typ_of_constant c) |
262 val tvars = typ_tvars (Linker.typ_of_constant c) |
260 val wrong = fold (fn n => fn wrong => wrong orelse is_none (Typtab.lookup tytab (TVar n))) tvars false |
263 val wrong = fold (fn n => fn wrong => wrong orelse is_none (Typtab.lookup tytab (TVar n))) tvars false |
261 in |
264 in |
262 if wrong then raise PCompute "right hand side of theorem contains type variables which do not occur on the left hand side" |
265 if wrong then raise PCompute "right hand side of theorem contains type variables which do not occur on the left hand side" |
263 else |
266 else |
264 if null (tvars) then |
267 if null (tvars) then |
265 check_const cs (c::cs') |
268 check_const cs (c::cs') |
266 else |
269 else |
267 check_const cs cs' |
270 check_const cs cs' |
268 end |
271 end |
269 | check_const [] cs' = cs' |
272 | check_const [] cs' = cs' |
270 val monocs = check_const right [] |
273 val monocs = check_const right [] |
271 in |
274 in |
272 if null (polycs) then |
275 if null (polycs) then |
273 (monocs, MonoThm th) |
276 (monocs, MonoThm th) |
274 else |
277 else |
275 (monocs, PolyThm (th, Linker.empty polycs, [])) |
278 (monocs, PolyThm (th, Linker.empty polycs, [])) |
276 end |
279 end |
277 |
280 |
278 fun create_computer machine thy ths = |
281 fun create_computer machine thy ths = |
279 let |
282 let |
280 fun add (MonoThm th) ths = th::ths |
283 fun add (MonoThm th) ths = th::ths |
281 | add (PolyThm (_, _, ths')) ths = ths'@ths |
284 | add (PolyThm (_, _, ths')) ths = ths'@ths |
282 val ths = fold_rev add ths [] |
285 val ths = fold_rev add ths [] |
283 in |
286 in |
284 Compute.make machine thy ths |
287 Compute.make machine thy ths |
285 end |
288 end |
286 |
289 |
287 fun conv_subst thy (subst : Type.tyenv) = |
290 fun conv_subst thy (subst : Type.tyenv) = |
288 map (fn (iname, (sort, ty)) => (ctyp_of thy (TVar (iname, sort)), ctyp_of thy ty)) (Vartab.dest subst) |
291 map (fn (iname, (sort, ty)) => (ctyp_of thy (TVar (iname, sort)), ctyp_of thy ty)) (Vartab.dest subst) |
289 |
292 |
290 fun add_monos thy monocs ths = |
293 fun add_monos thy monocs ths = |
291 let |
294 let |
292 val tsig = Sign.tsig_of thy |
295 val changed = ref false |
293 val changed = ref false |
296 fun add monocs (th as (MonoThm _)) = ([], th) |
294 fun add monocs (th as (MonoThm _)) = ([], th) |
297 | add monocs (PolyThm (th, instances, instanceths)) = |
295 | add monocs (PolyThm (th, instances, instanceths)) = |
298 let |
296 let |
299 val (newsubsts, instances) = Linker.add_instances thy instances monocs |
297 val (newsubsts, instances) = Linker.add_instances tsig instances monocs |
300 val _ = if not (null newsubsts) then changed := true else () |
298 val _ = if not (null newsubsts) then changed := true else () |
301 val newths = map (fn subst => Thm.instantiate (conv_subst thy subst, []) th) newsubsts |
299 val newths = map (fn subst => Thm.instantiate (conv_subst thy subst, []) th) newsubsts |
302 (* val _ = if not (null newths) then (print ("added new theorems: ", newths); ()) else ()*) |
300 (* val _ = if not (null newths) then (print ("added new theorems: ", newths); ()) else ()*) |
303 val newmonos = fold (fn th => fn monos => (snd (collect_consts_of_thm th))@monos) newths [] |
301 val newmonos = fold (fn th => fn monos => (snd (collect_consts_of_thm th))@monos) newths [] |
304 in |
302 in |
305 (newmonos, PolyThm (th, instances, instanceths@newths)) |
303 (newmonos, PolyThm (th, instances, instanceths@newths)) |
306 end |
304 end |
307 fun step monocs ths = |
305 fun step monocs ths = |
308 fold_rev (fn th => |
306 fold_rev (fn th => |
309 fn (newmonos, ths) => |
307 fn (newmonos, ths) => |
310 let val (newmonos', th') = add monocs th in |
308 let val (newmonos', th') = add monocs th in |
311 (newmonos'@newmonos, th'::ths) |
309 (newmonos'@newmonos, th'::ths) |
312 end) |
310 end) |
313 ths ([], []) |
311 ths ([], []) |
314 fun loop monocs ths = |
312 fun loop monocs ths = |
315 let val (monocs', ths') = step monocs ths in |
313 let val (monocs', ths') = step monocs ths in |
316 if null (monocs') then |
314 if null (monocs') then |
317 ths' |
315 ths' |
318 else |
316 else |
319 loop monocs' ths' |
317 loop monocs' ths' |
320 end |
318 end |
321 val result = loop monocs ths |
319 val result = loop monocs ths |
322 in |
320 in |
323 (!changed, result) |
321 (!changed, result) |
324 end |
322 end |
|
323 |
325 |
324 datatype cthm = ComputeThm of term list * sort list * term |
326 datatype cthm = ComputeThm of term list * sort list * term |
325 |
327 |
326 fun thm2cthm th = |
328 fun thm2cthm th = |
327 let |
329 let |
328 val {hyps, prop, shyps, ...} = Thm.rep_thm th |
330 val {hyps, prop, shyps, ...} = Thm.rep_thm th |
329 in |
331 in |
330 ComputeThm (hyps, shyps, prop) |
332 ComputeThm (hyps, shyps, prop) |
331 end |
333 end |
332 |
334 |
333 val cthm_ord' = prod_ord (prod_ord (list_ord Term.term_ord) (list_ord Term.sort_ord)) Term.term_ord |
335 val cthm_ord' = prod_ord (prod_ord (list_ord Term.term_ord) (list_ord Term.sort_ord)) Term.term_ord |
334 |
336 |
335 fun cthm_ord (ComputeThm (h1, sh1, p1), ComputeThm (h2, sh2, p2)) = cthm_ord' (((h1,sh1), p1), ((h2, sh2), p2)) |
337 fun cthm_ord (ComputeThm (h1, sh1, p1), ComputeThm (h2, sh2, p2)) = cthm_ord' (((h1,sh1), p1), ((h2, sh2), p2)) |
336 |
338 |
337 structure CThmtab = TableFun (type key = cthm val ord = cthm_ord) |
339 structure CThmtab = TableFun (type key = cthm val ord = cthm_ord) |
338 |
340 |
339 fun remove_duplicates ths = |
341 fun remove_duplicates ths = |
340 let |
342 let |
341 val counter = ref 0 |
343 val counter = ref 0 |
342 val tab = ref (CThmtab.empty : unit CThmtab.table) |
344 val tab = ref (CThmtab.empty : unit CThmtab.table) |
343 val thstab = ref (Inttab.empty : thm Inttab.table) |
345 val thstab = ref (Inttab.empty : thm Inttab.table) |
344 fun update th = |
346 fun update th = |
345 let |
347 let |
346 val key = thm2cthm th |
348 val key = thm2cthm th |
347 in |
349 in |
348 case CThmtab.lookup (!tab) key of |
350 case CThmtab.lookup (!tab) key of |
349 NONE => ((tab := CThmtab.update_new (key, ()) (!tab)); thstab := Inttab.update_new (!counter, th) (!thstab); counter := !counter + 1) |
351 NONE => ((tab := CThmtab.update_new (key, ()) (!tab)); thstab := Inttab.update_new (!counter, th) (!thstab); counter := !counter + 1) |
350 | _ => () |
352 | _ => () |
351 end |
353 end |
352 val _ = map update ths |
354 val _ = map update ths |
353 in |
355 in |
354 map snd (Inttab.dest (!thstab)) |
356 map snd (Inttab.dest (!thstab)) |
355 end |
357 end |
356 |
358 |
357 |
359 |
358 fun make machine thy ths cs = |
360 fun make machine thy ths cs = |
359 let |
361 let |
360 val ths = remove_duplicates ths |
362 val ths = remove_duplicates ths |
361 val (monocs, ths) = fold_rev (fn th => |
363 val (monocs, ths) = fold_rev (fn th => |
362 fn (monocs, ths) => |
364 fn (monocs, ths) => |
363 let val (m, t) = create_theorem th in |
365 let val (m, t) = create_theorem th in |
364 (m@monocs, t::ths) |
366 (m@monocs, t::ths) |
365 end) |
367 end) |
366 ths (cs, []) |
368 ths (cs, []) |
367 val (_, ths) = add_monos thy monocs ths |
369 val (_, ths) = add_monos thy monocs ths |
368 val computer = create_computer machine thy ths |
370 val computer = create_computer machine thy ths |
369 in |
371 in |
370 PComputer (machine, Theory.check_thy thy, ref computer, ref ths) |
372 PComputer (machine, Theory.check_thy thy, ref computer, ref ths) |
371 end |
373 end |
372 |
374 |
373 fun add_instances (PComputer (machine, thyref, rcomputer, rths)) cs = |
375 fun add_instances (PComputer (machine, thyref, rcomputer, rths)) cs = |
374 let |
376 let |
375 val thy = Theory.deref thyref |
377 val thy = Theory.deref thyref |
376 val (changed, ths) = add_monos thy cs (!rths) |
378 val (changed, ths) = add_monos thy cs (!rths) |
377 in |
379 in |
378 if changed then |
380 if changed then |
379 (rcomputer := create_computer machine thy ths; |
381 (rcomputer := create_computer machine thy ths; |
380 rths := ths; |
382 rths := ths; |
381 true) |
383 true) |
382 else |
384 else |
383 false |
385 false |
384 end |
386 end |
385 |
387 |
386 fun rewrite (pc as PComputer (_, _, rcomputer, _)) cts = |
388 fun rewrite (pc as PComputer (_, _, rcomputer, _)) cts = |
387 let |
389 let |
388 val _ = map (fn ct => add_instances pc (Linker.collect_consts [term_of ct])) cts |
390 val _ = map (fn ct => add_instances pc (Linker.collect_consts [term_of ct])) cts |
389 in |
391 in |
390 map (fn ct => Compute.rewrite (!rcomputer) ct) cts |
392 map (fn ct => Compute.rewrite (!rcomputer) ct) cts |
391 end |
393 end |
392 |
394 |
393 end |
395 end |