13 |
13 |
14 (* Functions designated with a ! in front of them actually update the computer parameter *) |
14 (* Functions designated with a ! in front of them actually update the computer parameter *) |
15 |
15 |
16 exception Make of string |
16 exception Make of string |
17 val make : machine -> theory -> thm list -> computer |
17 val make : machine -> theory -> thm list -> computer |
|
18 val make_with_cache : machine -> theory -> term list -> thm list -> computer |
18 val theory_of : computer -> theory |
19 val theory_of : computer -> theory |
19 val hyps_of : computer -> term list |
20 val hyps_of : computer -> term list |
20 val shyps_of : computer -> sort list |
21 val shyps_of : computer -> sort list |
21 (* ! *) val update : computer -> thm list -> unit |
22 (* ! *) val update : computer -> thm list -> unit |
|
23 (* ! *) val update_with_cache : computer -> term list -> thm list -> unit |
22 (* ! *) val discard : computer -> unit |
24 (* ! *) val discard : computer -> unit |
23 |
25 |
24 (* ! *) val set_naming : computer -> naming -> unit |
26 (* ! *) val set_naming : computer -> naming -> unit |
25 val naming_of : computer -> naming |
27 val naming_of : computer -> naming |
26 |
28 |
33 (* ! *) val evaluate_prem : computer -> int -> theorem -> theorem |
35 (* ! *) val evaluate_prem : computer -> int -> theorem -> theorem |
34 (* ! *) val modus_ponens : computer -> int -> thm -> theorem -> theorem |
36 (* ! *) val modus_ponens : computer -> int -> thm -> theorem -> theorem |
35 |
37 |
36 val setup_compute : theory -> theory |
38 val setup_compute : theory -> theory |
37 |
39 |
38 val print_encoding : bool ref |
|
39 |
|
40 end |
40 end |
41 |
41 |
42 structure Compute :> COMPUTE = struct |
42 structure Compute :> COMPUTE = struct |
43 |
43 |
44 open Report; |
44 open Report; |
45 |
|
46 val print_encoding = ref false |
|
47 |
45 |
48 datatype machine = BARRAS | BARRAS_COMPILED | HASKELL | SML |
46 datatype machine = BARRAS | BARRAS_COMPILED | HASKELL | SML |
49 |
47 |
50 (* Terms are mapped to integer codes *) |
48 (* Terms are mapped to integer codes *) |
51 structure Encode :> |
49 structure Encode :> |
55 val insert : term -> encoding -> int * encoding |
53 val insert : term -> encoding -> int * encoding |
56 val lookup_code : term -> encoding -> int option |
54 val lookup_code : term -> encoding -> int option |
57 val lookup_term : int -> encoding -> term option |
55 val lookup_term : int -> encoding -> term option |
58 val remove_code : int -> encoding -> encoding |
56 val remove_code : int -> encoding -> encoding |
59 val remove_term : term -> encoding -> encoding |
57 val remove_term : term -> encoding -> encoding |
60 val fold : ((term * int) -> 'a -> 'a) -> encoding -> 'a -> 'a |
58 val fold : ((term * int) -> 'a -> 'a) -> encoding -> 'a -> 'a |
61 end |
59 end |
62 = |
60 = |
63 struct |
61 struct |
64 |
62 |
65 type encoding = int * (int Termtab.table) * (term Inttab.table) |
63 type encoding = int * (int Termtab.table) * (term Inttab.table) |
79 (case lookup_term c e of NONE => e | SOME t => (count, Termtab.delete t term2int, Inttab.delete c int2term)) |
77 (case lookup_term c e of NONE => e | SOME t => (count, Termtab.delete t term2int, Inttab.delete c int2term)) |
80 |
78 |
81 fun remove_term t (e as (count, term2int, int2term)) = |
79 fun remove_term t (e as (count, term2int, int2term)) = |
82 (case lookup_code t e of NONE => e | SOME c => (count, Termtab.delete t term2int, Inttab.delete c int2term)) |
80 (case lookup_code t e of NONE => e | SOME c => (count, Termtab.delete t term2int, Inttab.delete c int2term)) |
83 |
81 |
84 fun fold f (_, term2int, _) = Termtab.fold f term2int |
82 fun fold f (_, term2int, _) = Termtab.fold f term2int |
85 |
83 |
86 end |
84 end |
87 |
85 |
88 exception Make of string; |
86 exception Make of string; |
89 exception Compute of string; |
87 exception Compute of string; |
204 val _ = if not (null tpairs) then raise Make "theorems may not contain tpairs" else () |
202 val _ = if not (null tpairs) then raise Make "theorems may not contain tpairs" else () |
205 in |
203 in |
206 ComputeThm (hyps, shyps, prop) |
204 ComputeThm (hyps, shyps, prop) |
207 end |
205 end |
208 |
206 |
209 fun make_internal machine thy stamp encoding raw_ths = |
207 fun make_internal machine thy stamp encoding cache_pattern_terms raw_ths = |
210 let |
208 let |
211 fun transfer (x:thm) = Thm.transfer thy x |
209 fun transfer (x:thm) = Thm.transfer thy x |
212 val ths = map (thm2cthm o Thm.strip_shyps o transfer) raw_ths |
210 val ths = map (thm2cthm o Thm.strip_shyps o transfer) raw_ths |
|
211 |
|
212 fun make_pattern encoding n vars (var as AbstractMachine.Abs _) = |
|
213 raise (Make "no lambda abstractions allowed in pattern") |
|
214 | make_pattern encoding n vars (var as AbstractMachine.Var _) = |
|
215 raise (Make "no bound variables allowed in pattern") |
|
216 | make_pattern encoding n vars (AbstractMachine.Const code) = |
|
217 (case the (Encode.lookup_term code encoding) of |
|
218 Var _ => ((n+1, Inttab.update_new (code, n) vars, AbstractMachine.PVar) |
|
219 handle Inttab.DUP _ => raise (Make "no duplicate variable in pattern allowed")) |
|
220 | _ => (n, vars, AbstractMachine.PConst (code, []))) |
|
221 | make_pattern encoding n vars (AbstractMachine.App (a, b)) = |
|
222 let |
|
223 val (n, vars, pa) = make_pattern encoding n vars a |
|
224 val (n, vars, pb) = make_pattern encoding n vars b |
|
225 in |
|
226 case pa of |
|
227 AbstractMachine.PVar => |
|
228 raise (Make "patterns may not start with a variable") |
|
229 | AbstractMachine.PConst (c, args) => |
|
230 (n, vars, AbstractMachine.PConst (c, args@[pb])) |
|
231 end |
213 |
232 |
214 fun thm2rule (encoding, hyptable, shyptable) th = |
233 fun thm2rule (encoding, hyptable, shyptable) th = |
215 let |
234 let |
216 val (ComputeThm (hyps, shyps, prop)) = th |
235 val (ComputeThm (hyps, shyps, prop)) = th |
217 val hyptable = fold (fn h => Termtab.update (h, ())) hyps hyptable |
236 val hyptable = fold (fn h => Termtab.update (h, ())) hyps hyptable |
232 val (encoding, t2) = remove_types encoding t2 |
251 val (encoding, t2) = remove_types encoding t2 |
233 in |
252 in |
234 (encoding, AbstractMachine.Guard (t1, t2)) |
253 (encoding, AbstractMachine.Guard (t1, t2)) |
235 end handle TERM _ => raise (Make "guards must be meta-level equations")) |
254 end handle TERM _ => raise (Make "guards must be meta-level equations")) |
236 val (encoding, prems) = fold_rev (fn p => fn (encoding, ps) => let val (e, p) = remove_types_of_guard encoding p in (e, p::ps) end) prems (encoding, []) |
255 val (encoding, prems) = fold_rev (fn p => fn (encoding, ps) => let val (e, p) = remove_types_of_guard encoding p in (e, p::ps) end) prems (encoding, []) |
237 |
|
238 fun make_pattern encoding n vars (var as AbstractMachine.Abs _) = |
|
239 raise (Make "no lambda abstractions allowed in pattern") |
|
240 | make_pattern encoding n vars (var as AbstractMachine.Var _) = |
|
241 raise (Make "no bound variables allowed in pattern") |
|
242 | make_pattern encoding n vars (AbstractMachine.Const code) = |
|
243 (case the (Encode.lookup_term code encoding) of |
|
244 Var _ => ((n+1, Inttab.update_new (code, n) vars, AbstractMachine.PVar) |
|
245 handle Inttab.DUP _ => raise (Make "no duplicate variable in pattern allowed")) |
|
246 | _ => (n, vars, AbstractMachine.PConst (code, []))) |
|
247 | make_pattern encoding n vars (AbstractMachine.App (a, b)) = |
|
248 let |
|
249 val (n, vars, pa) = make_pattern encoding n vars a |
|
250 val (n, vars, pb) = make_pattern encoding n vars b |
|
251 in |
|
252 case pa of |
|
253 AbstractMachine.PVar => |
|
254 raise (Make "patterns may not start with a variable") |
|
255 | AbstractMachine.PConst (c, args) => |
|
256 (n, vars, AbstractMachine.PConst (c, args@[pb])) |
|
257 end |
|
258 |
256 |
259 (* Principally, a check should be made here to see if the (meta-) hyps contain any of the variables of the rule. |
257 (* Principally, a check should be made here to see if the (meta-) hyps contain any of the variables of the rule. |
260 As it is, all variables of the rule are schematic, and there are no schematic variables in meta-hyps, therefore |
258 As it is, all variables of the rule are schematic, and there are no schematic variables in meta-hyps, therefore |
261 this check can be left out. *) |
259 this check can be left out. *) |
262 |
260 |
292 let |
290 let |
293 val (encoding_hyptable, rule) = thm2rule encoding_hyptable th |
291 val (encoding_hyptable, rule) = thm2rule encoding_hyptable th |
294 in (encoding_hyptable, rule::rules) end) |
292 in (encoding_hyptable, rule::rules) end) |
295 ths ((encoding, Termtab.empty, Sorttab.empty), []) |
293 ths ((encoding, Termtab.empty, Sorttab.empty), []) |
296 |
294 |
|
295 fun make_cache_pattern t (encoding, cache_patterns) = |
|
296 let |
|
297 val (encoding, a) = remove_types encoding t |
|
298 val (_,_,p) = make_pattern encoding 0 Inttab.empty a |
|
299 in |
|
300 (encoding, p::cache_patterns) |
|
301 end |
|
302 |
|
303 val (encoding, cache_patterns) = fold_rev make_cache_pattern cache_pattern_terms (encoding, []) |
|
304 |
|
305 fun arity (Type ("fun", [a,b])) = 1 + arity b |
|
306 | arity _ = 0 |
|
307 |
|
308 fun make_arity (Const (s, _), i) tab = |
|
309 (Inttab.update (i, arity (Sign.the_const_type thy s)) tab handle TYPE _ => tab) |
|
310 | make_arity _ tab = tab |
|
311 |
|
312 val const_arity_tab = Encode.fold make_arity encoding Inttab.empty |
|
313 fun const_arity x = Inttab.lookup const_arity_tab x |
|
314 |
297 val prog = |
315 val prog = |
298 case machine of |
316 case machine of |
299 BARRAS => ProgBarras (AM_Interpreter.compile rules) |
317 BARRAS => ProgBarras (AM_Interpreter.compile cache_patterns const_arity rules) |
300 | BARRAS_COMPILED => ProgBarrasC (AM_Compiler.compile rules) |
318 | BARRAS_COMPILED => ProgBarrasC (AM_Compiler.compile cache_patterns const_arity rules) |
301 | HASKELL => ProgHaskell (AM_GHC.compile rules) |
319 | HASKELL => ProgHaskell (AM_GHC.compile cache_patterns const_arity rules) |
302 | SML => ProgSML (AM_SML.compile rules) |
320 | SML => ProgSML (AM_SML.compile cache_patterns const_arity rules) |
303 |
321 |
304 fun has_witness s = not (null (Sign.witness_sorts thy [] [s])) |
322 fun has_witness s = not (null (Sign.witness_sorts thy [] [s])) |
305 |
323 |
306 val shyptable = fold Sorttab.delete (filter has_witness (Sorttab.keys (shyptable))) shyptable |
324 val shyptable = fold Sorttab.delete (filter has_witness (Sorttab.keys (shyptable))) shyptable |
307 |
325 |
308 in (Theory.check_thy thy, encoding, Termtab.keys hyptable, shyptable, prog, stamp, default_naming) end |
326 in (Theory.check_thy thy, encoding, Termtab.keys hyptable, shyptable, prog, stamp, default_naming) end |
309 |
327 |
310 fun make machine thy raw_thms = Computer (ref (SOME (make_internal machine thy (ref ()) Encode.empty raw_thms))) |
328 fun make_with_cache machine thy cache_patterns raw_thms = Computer (ref (SOME (make_internal machine thy (ref ()) Encode.empty cache_patterns raw_thms))) |
311 |
329 |
312 fun update computer raw_thms = |
330 fun make machine thy raw_thms = make_with_cache machine thy [] raw_thms |
|
331 |
|
332 fun update_with_cache computer cache_patterns raw_thms = |
313 let |
333 let |
314 val c = make_internal (machine_of_prog (prog_of computer)) (theory_of computer) (stamp_of computer) |
334 val c = make_internal (machine_of_prog (prog_of computer)) (theory_of computer) (stamp_of computer) |
315 (encoding_of computer) raw_thms |
335 (encoding_of computer) cache_patterns raw_thms |
316 val _ = (ref_of computer) := SOME c |
336 val _ = (ref_of computer) := SOME c |
317 in |
337 in |
318 () |
338 () |
319 end |
339 end |
|
340 |
|
341 fun update computer raw_thms = update_with_cache computer [] raw_thms |
320 |
342 |
321 fun discard computer = |
343 fun discard computer = |
322 let |
344 let |
323 val _ = |
345 val _ = |
324 case prog_of computer of |
346 case prog_of computer of |