src/Tools/Compute_Oracle/compute.ML
changeset 25520 e123c81257a5
parent 25218 fcf0f50e478c
child 26626 c6231d64d264
equal deleted inserted replaced
25519:8570745cb40b 25520:e123c81257a5
    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