src/Tools/Compute_Oracle/compute.ML
changeset 26626 c6231d64d264
parent 25520 e123c81257a5
child 26674 fe93963ed76d
equal deleted inserted replaced
26625:e0cc4169626e 26626:c6231d64d264
    41 
    41 
    42 structure Compute :> COMPUTE = struct
    42 structure Compute :> COMPUTE = struct
    43 
    43 
    44 open Report;
    44 open Report;
    45 
    45 
    46 datatype machine = BARRAS | BARRAS_COMPILED | HASKELL | SML	 
    46 datatype machine = BARRAS | BARRAS_COMPILED | HASKELL | SML      
    47 
    47 
    48 (* Terms are mapped to integer codes *)
    48 (* Terms are mapped to integer codes *)
    49 structure Encode :> 
    49 structure Encode :> 
    50 sig
    50 sig
    51     type encoding
    51     type encoding
    52     val empty : encoding
    52     val empty : encoding
    53     val insert : term -> encoding -> int * encoding
    53     val insert : term -> encoding -> int * encoding
    54     val lookup_code : term -> encoding -> int option
    54     val lookup_code : term -> encoding -> int option
    55     val lookup_term : int -> encoding -> term option					
    55     val lookup_term : int -> encoding -> term option                                    
    56     val remove_code : int -> encoding -> encoding
    56     val remove_code : int -> encoding -> encoding
    57     val remove_term : term -> encoding -> encoding
    57     val remove_term : term -> encoding -> encoding
    58     val fold : ((term * int) -> 'a -> 'a) -> encoding -> 'a -> 'a  						       
    58     val fold : ((term * int) -> 'a -> 'a) -> encoding -> 'a -> 'a                                                      
    59 end 
    59 end 
    60 = 
    60 = 
    61 struct
    61 struct
    62 
    62 
    63 type encoding = int * (int Termtab.table) * (term Inttab.table)
    63 type encoding = int * (int Termtab.table) * (term Inttab.table)
    64 
    64 
    65 val empty = (0, Termtab.empty, Inttab.empty)
    65 val empty = (0, Termtab.empty, Inttab.empty)
    66 
    66 
    67 fun insert t (e as (count, term2int, int2term)) = 
    67 fun insert t (e as (count, term2int, int2term)) = 
    68     (case Termtab.lookup term2int t of
    68     (case Termtab.lookup term2int t of
    69 	 NONE => (count, (count+1, Termtab.update_new (t, count) term2int, Inttab.update_new (count, t) int2term))
    69          NONE => (count, (count+1, Termtab.update_new (t, count) term2int, Inttab.update_new (count, t) int2term))
    70        | SOME code => (code, e))
    70        | SOME code => (code, e))
    71 
    71 
    72 fun lookup_code t (_, term2int, _) = Termtab.lookup term2int t
    72 fun lookup_code t (_, term2int, _) = Termtab.lookup term2int t
    73 
    73 
    74 fun lookup_term c (_, _, int2term) = Inttab.lookup int2term c
    74 fun lookup_term c (_, _, int2term) = Inttab.lookup int2term c
    86 exception Make of string;
    86 exception Make of string;
    87 exception Compute of string;
    87 exception Compute of string;
    88 
    88 
    89 local
    89 local
    90     fun make_constant t ty encoding = 
    90     fun make_constant t ty encoding = 
    91 	let 
    91         let 
    92 	    val (code, encoding) = Encode.insert t encoding 
    92             val (code, encoding) = Encode.insert t encoding 
    93 	in 
    93         in 
    94 	    (encoding, AbstractMachine.Const code)
    94             (encoding, AbstractMachine.Const code)
    95 	end
    95         end
    96 in
    96 in
    97 
    97 
    98 fun remove_types encoding t =
    98 fun remove_types encoding t =
    99     case t of 
    99     case t of 
   100 	Var (_, ty) => make_constant t ty encoding
   100         Var (_, ty) => make_constant t ty encoding
   101       | Free (_, ty) => make_constant t ty encoding
   101       | Free (_, ty) => make_constant t ty encoding
   102       | Const (_, ty) => make_constant t ty encoding
   102       | Const (_, ty) => make_constant t ty encoding
   103       | Abs (_, ty, t') => 
   103       | Abs (_, ty, t') => 
   104 	let val (encoding, t'') = remove_types encoding t' in
   104         let val (encoding, t'') = remove_types encoding t' in
   105 	    (encoding, AbstractMachine.Abs t'')
   105             (encoding, AbstractMachine.Abs t'')
   106 	end
   106         end
   107       | a $ b => 
   107       | a $ b => 
   108 	let
   108         let
   109 	    val (encoding, a) = remove_types encoding a
   109             val (encoding, a) = remove_types encoding a
   110 	    val (encoding, b) = remove_types encoding b
   110             val (encoding, b) = remove_types encoding b
   111 	in
   111         in
   112 	    (encoding, AbstractMachine.App (a,b))
   112             (encoding, AbstractMachine.App (a,b))
   113 	end
   113         end
   114       | Bound b => (encoding, AbstractMachine.Var b)
   114       | Bound b => (encoding, AbstractMachine.Var b)
   115 end
   115 end
   116     
   116     
   117 local
   117 local
   118     fun type_of (Free (_, ty)) = ty
   118     fun type_of (Free (_, ty)) = ty
   121       | type_of _ = sys_error "infer_types: type_of error"
   121       | type_of _ = sys_error "infer_types: type_of error"
   122 in
   122 in
   123 fun infer_types naming encoding =
   123 fun infer_types naming encoding =
   124     let
   124     let
   125         fun infer_types _ bounds _ (AbstractMachine.Var v) = (Bound v, List.nth (bounds, v))
   125         fun infer_types _ bounds _ (AbstractMachine.Var v) = (Bound v, List.nth (bounds, v))
   126 	  | infer_types _ bounds _ (AbstractMachine.Const code) = 
   126           | infer_types _ bounds _ (AbstractMachine.Const code) = 
   127 	    let
   127             let
   128 		val c = the (Encode.lookup_term code encoding)
   128                 val c = the (Encode.lookup_term code encoding)
   129 	    in
   129             in
   130 		(c, type_of c)
   130                 (c, type_of c)
   131 	    end
   131             end
   132 	  | infer_types level bounds _ (AbstractMachine.App (a, b)) = 
   132           | infer_types level bounds _ (AbstractMachine.App (a, b)) = 
   133 	    let
   133             let
   134 		val (a, aty) = infer_types level bounds NONE a
   134                 val (a, aty) = infer_types level bounds NONE a
   135 		val (adom, arange) =
   135                 val (adom, arange) =
   136                     case aty of
   136                     case aty of
   137                         Type ("fun", [dom, range]) => (dom, range)
   137                         Type ("fun", [dom, range]) => (dom, range)
   138                       | _ => sys_error "infer_types: function type expected"
   138                       | _ => sys_error "infer_types: function type expected"
   139                 val (b, bty) = infer_types level bounds (SOME adom) b
   139                 val (b, bty) = infer_types level bounds (SOME adom) b
   140 	    in
   140             in
   141 		(a $ b, arange)
   141                 (a $ b, arange)
   142 	    end
   142             end
   143           | infer_types level bounds (SOME (ty as Type ("fun", [dom, range]))) (AbstractMachine.Abs m) =
   143           | infer_types level bounds (SOME (ty as Type ("fun", [dom, range]))) (AbstractMachine.Abs m) =
   144             let
   144             let
   145                 val (m, _) = infer_types (level+1) (dom::bounds) (SOME range) m
   145                 val (m, _) = infer_types (level+1) (dom::bounds) (SOME range) m
   146             in
   146             in
   147                 (Abs (naming level, dom, m), ty)
   147                 (Abs (naming level, dom, m), ty)
   158         infer
   158         infer
   159     end
   159     end
   160 end
   160 end
   161 
   161 
   162 datatype prog = 
   162 datatype prog = 
   163 	 ProgBarras of AM_Interpreter.program 
   163          ProgBarras of AM_Interpreter.program 
   164        | ProgBarrasC of AM_Compiler.program
   164        | ProgBarrasC of AM_Compiler.program
   165        | ProgHaskell of AM_GHC.program
   165        | ProgHaskell of AM_GHC.program
   166        | ProgSML of AM_SML.program
   166        | ProgSML of AM_SML.program
   167 
   167 
   168 fun machine_of_prog (ProgBarras _) = BARRAS
   168 fun machine_of_prog (ProgBarras _) = BARRAS
   196 
   196 
   197 datatype cthm = ComputeThm of term list * sort list * term
   197 datatype cthm = ComputeThm of term list * sort list * term
   198 
   198 
   199 fun thm2cthm th = 
   199 fun thm2cthm th = 
   200     let
   200     let
   201 	val {hyps, prop, tpairs, shyps, ...} = Thm.rep_thm th
   201         val {hyps, prop, tpairs, shyps, ...} = Thm.rep_thm th
   202 	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 ()
   203     in
   203     in
   204 	ComputeThm (hyps, shyps, prop)
   204         ComputeThm (hyps, shyps, prop)
   205     end
   205     end
   206 
   206 
   207 fun make_internal machine thy stamp encoding cache_pattern_terms raw_ths =
   207 fun make_internal machine thy stamp encoding cache_pattern_terms raw_ths =
   208     let
   208     let
   209 	fun transfer (x:thm) = Thm.transfer thy x
   209         fun transfer (x:thm) = Thm.transfer thy x
   210 	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 
   211 
   212         fun make_pattern encoding n vars (var as AbstractMachine.Abs _) =
   212         fun make_pattern encoding n vars (var as AbstractMachine.Abs _) =
   213 	    raise (Make "no lambda abstractions allowed in pattern")
   213             raise (Make "no lambda abstractions allowed in pattern")
   214 	  | make_pattern encoding n vars (var as AbstractMachine.Var _) =
   214           | make_pattern encoding n vars (var as AbstractMachine.Var _) =
   215 	    raise (Make "no bound variables allowed in pattern")
   215             raise (Make "no bound variables allowed in pattern")
   216 	  | make_pattern encoding n vars (AbstractMachine.Const code) =
   216           | make_pattern encoding n vars (AbstractMachine.Const code) =
   217 	    (case the (Encode.lookup_term code encoding) of
   217             (case the (Encode.lookup_term code encoding) of
   218 		 Var _ => ((n+1, Inttab.update_new (code, n) vars, AbstractMachine.PVar)
   218                  Var _ => ((n+1, Inttab.update_new (code, n) vars, AbstractMachine.PVar)
   219 			   handle Inttab.DUP _ => raise (Make "no duplicate variable in pattern allowed"))
   219                            handle Inttab.DUP _ => raise (Make "no duplicate variable in pattern allowed"))
   220 	       | _ => (n, vars, AbstractMachine.PConst (code, [])))
   220                | _ => (n, vars, AbstractMachine.PConst (code, [])))
   221           | make_pattern encoding n vars (AbstractMachine.App (a, b)) =
   221           | make_pattern encoding n vars (AbstractMachine.App (a, b)) =
   222             let
   222             let
   223                 val (n, vars, pa) = make_pattern encoding n vars a
   223                 val (n, vars, pa) = make_pattern encoding n vars a
   224                 val (n, vars, pb) = make_pattern encoding n vars b
   224                 val (n, vars, pb) = make_pattern encoding n vars b
   225             in
   225             in
   230                     (n, vars, AbstractMachine.PConst (c, args@[pb]))
   230                     (n, vars, AbstractMachine.PConst (c, args@[pb]))
   231             end
   231             end
   232 
   232 
   233         fun thm2rule (encoding, hyptable, shyptable) th =
   233         fun thm2rule (encoding, hyptable, shyptable) th =
   234             let
   234             let
   235 		val (ComputeThm (hyps, shyps, prop)) = th
   235                 val (ComputeThm (hyps, shyps, prop)) = th
   236 		val hyptable = fold (fn h => Termtab.update (h, ())) hyps hyptable
   236                 val hyptable = fold (fn h => Termtab.update (h, ())) hyps hyptable
   237 		val shyptable = fold (fn sh => Sorttab.update (sh, ())) shyps shyptable
   237                 val shyptable = fold (fn sh => Sorttab.update (sh, ())) shyps shyptable
   238 		val (prems, prop) = (Logic.strip_imp_prems prop, Logic.strip_imp_concl prop)
   238                 val (prems, prop) = (Logic.strip_imp_prems prop, Logic.strip_imp_concl prop)
   239                 val (a, b) = Logic.dest_equals prop
   239                 val (a, b) = Logic.dest_equals prop
   240                   handle TERM _ => raise (Make "theorems must be meta-level equations (with optional guards)")
   240                   handle TERM _ => raise (Make "theorems must be meta-level equations (with optional guards)")
   241 		val a = Envir.eta_contract a
   241                 val a = Envir.eta_contract a
   242 		val b = Envir.eta_contract b
   242                 val b = Envir.eta_contract b
   243 		val prems = map Envir.eta_contract prems
   243                 val prems = map Envir.eta_contract prems
   244 
   244 
   245                 val (encoding, left) = remove_types encoding a     
   245                 val (encoding, left) = remove_types encoding a     
   246 		val (encoding, right) = remove_types encoding b  
   246                 val (encoding, right) = remove_types encoding b  
   247                 fun remove_types_of_guard encoding g = 
   247                 fun remove_types_of_guard encoding g = 
   248 		    (let
   248                     (let
   249 			 val (t1, t2) = Logic.dest_equals g 
   249                          val (t1, t2) = Logic.dest_equals g 
   250 			 val (encoding, t1) = remove_types encoding t1
   250                          val (encoding, t1) = remove_types encoding t1
   251 			 val (encoding, t2) = remove_types encoding t2
   251                          val (encoding, t2) = remove_types encoding t2
   252 		     in
   252                      in
   253 			 (encoding, AbstractMachine.Guard (t1, t2))
   253                          (encoding, AbstractMachine.Guard (t1, t2))
   254 		     end handle TERM _ => raise (Make "guards must be meta-level equations"))
   254                      end handle TERM _ => raise (Make "guards must be meta-level equations"))
   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, [])
   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, [])
   256 
   256 
   257                 (* 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.
   258                    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
   259                    this check can be left out. *)
   259                    this check can be left out. *)
   261                 val (vcount, vars, pattern) = make_pattern encoding 0 Inttab.empty left
   261                 val (vcount, vars, pattern) = make_pattern encoding 0 Inttab.empty left
   262                 val _ = (case pattern of
   262                 val _ = (case pattern of
   263                              AbstractMachine.PVar =>
   263                              AbstractMachine.PVar =>
   264                              raise (Make "patterns may not start with a variable")
   264                              raise (Make "patterns may not start with a variable")
   265                          (*  | AbstractMachine.PConst (_, []) => 
   265                          (*  | AbstractMachine.PConst (_, []) => 
   266 			     (print th; raise (Make "no parameter rewrite found"))*)
   266                              (print th; raise (Make "no parameter rewrite found"))*)
   267 			   | _ => ())
   267                            | _ => ())
   268 
   268 
   269                 (* finally, provide a function for renaming the
   269                 (* finally, provide a function for renaming the
   270                    pattern bound variables on the right hand side *)
   270                    pattern bound variables on the right hand side *)
   271 
   271 
   272                 fun rename level vars (var as AbstractMachine.Var _) = var
   272                 fun rename level vars (var as AbstractMachine.Var _) = var
   273 		  | rename level vars (c as AbstractMachine.Const code) =
   273                   | rename level vars (c as AbstractMachine.Const code) =
   274 		    (case Inttab.lookup vars code of 
   274                     (case Inttab.lookup vars code of 
   275 			 NONE => c 
   275                          NONE => c 
   276 		       | SOME n => AbstractMachine.Var (vcount-n-1+level))
   276                        | SOME n => AbstractMachine.Var (vcount-n-1+level))
   277                   | rename level vars (AbstractMachine.App (a, b)) =
   277                   | rename level vars (AbstractMachine.App (a, b)) =
   278                     AbstractMachine.App (rename level vars a, rename level vars b)
   278                     AbstractMachine.App (rename level vars a, rename level vars b)
   279                   | rename level vars (AbstractMachine.Abs m) =
   279                   | rename level vars (AbstractMachine.Abs m) =
   280                     AbstractMachine.Abs (rename (level+1) vars m)
   280                     AbstractMachine.Abs (rename (level+1) vars m)
   281 		    
   281                     
   282 		fun rename_guard (AbstractMachine.Guard (a,b)) = 
   282                 fun rename_guard (AbstractMachine.Guard (a,b)) = 
   283 		    AbstractMachine.Guard (rename 0 vars a, rename 0 vars b)
   283                     AbstractMachine.Guard (rename 0 vars a, rename 0 vars b)
   284             in
   284             in
   285                 ((encoding, hyptable, shyptable), (map rename_guard prems, pattern, rename 0 vars right))
   285                 ((encoding, hyptable, shyptable), (map rename_guard prems, pattern, rename 0 vars right))
   286             end
   286             end
   287 
   287 
   288         val ((encoding, hyptable, shyptable), rules) =
   288         val ((encoding, hyptable, shyptable), rules) =
   291               val (encoding_hyptable, rule) = thm2rule encoding_hyptable th
   291               val (encoding_hyptable, rule) = thm2rule encoding_hyptable th
   292             in (encoding_hyptable, rule::rules) end)
   292             in (encoding_hyptable, rule::rules) end)
   293           ths ((encoding, Termtab.empty, Sorttab.empty), [])
   293           ths ((encoding, Termtab.empty, Sorttab.empty), [])
   294 
   294 
   295         fun make_cache_pattern t (encoding, cache_patterns) =
   295         fun make_cache_pattern t (encoding, cache_patterns) =
   296 	    let
   296             let
   297 		val (encoding, a) = remove_types encoding t
   297                 val (encoding, a) = remove_types encoding t
   298 		val (_,_,p) = make_pattern encoding 0 Inttab.empty a
   298                 val (_,_,p) = make_pattern encoding 0 Inttab.empty a
   299 	    in
   299             in
   300 		(encoding, p::cache_patterns)
   300                 (encoding, p::cache_patterns)
   301 	    end
   301             end
   302 	
   302         
   303 	val (encoding, cache_patterns) = fold_rev make_cache_pattern cache_pattern_terms (encoding, [])
   303         val (encoding, cache_patterns) = fold_rev make_cache_pattern cache_pattern_terms (encoding, [])
   304 
   304 
   305 	fun arity (Type ("fun", [a,b])) = 1 + arity b
   305         fun arity (Type ("fun", [a,b])) = 1 + arity b
   306 	  | arity _ = 0
   306           | arity _ = 0
   307 
   307 
   308 	fun make_arity (Const (s, _), i) tab = 
   308         fun make_arity (Const (s, _), i) tab = 
   309 	    (Inttab.update (i, arity (Sign.the_const_type thy s)) tab handle TYPE _ => tab)
   309             (Inttab.update (i, arity (Sign.the_const_type thy s)) tab handle TYPE _ => tab)
   310 	  | make_arity _ tab = tab
   310           | make_arity _ tab = tab
   311 
   311 
   312 	val const_arity_tab = Encode.fold make_arity encoding Inttab.empty
   312         val const_arity_tab = Encode.fold make_arity encoding Inttab.empty
   313 	fun const_arity x = Inttab.lookup const_arity_tab x 
   313         fun const_arity x = Inttab.lookup const_arity_tab x 
   314 
   314 
   315         val prog = 
   315         val prog = 
   316 	    case machine of 
   316             case machine of 
   317 		BARRAS => ProgBarras (AM_Interpreter.compile cache_patterns const_arity rules)
   317                 BARRAS => ProgBarras (AM_Interpreter.compile cache_patterns const_arity rules)
   318 	      | BARRAS_COMPILED => ProgBarrasC (AM_Compiler.compile cache_patterns const_arity rules)
   318               | BARRAS_COMPILED => ProgBarrasC (AM_Compiler.compile cache_patterns const_arity rules)
   319 	      | HASKELL => ProgHaskell (AM_GHC.compile cache_patterns const_arity rules)
   319               | HASKELL => ProgHaskell (AM_GHC.compile cache_patterns const_arity rules)
   320 	      | SML => ProgSML (AM_SML.compile cache_patterns const_arity rules)
   320               | SML => ProgSML (AM_SML.compile cache_patterns const_arity rules)
   321 
   321 
   322         fun has_witness s = not (null (Sign.witness_sorts thy [] [s]))
   322         fun has_witness s = not (null (Sign.witness_sorts thy [] [s]))
   323 
   323 
   324 	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
   325 
   325 
   326     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
   327 
   327 
   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)))
   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)))
   329 
   329 
   330 fun make machine thy raw_thms = make_with_cache machine thy [] raw_thms
   330 fun make machine thy raw_thms = make_with_cache machine thy [] raw_thms
   331 
   331 
   332 fun update_with_cache computer cache_patterns raw_thms =
   332 fun update_with_cache computer cache_patterns raw_thms =
   333     let 
   333     let 
   334 	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) 
   335 			      (encoding_of computer) cache_patterns raw_thms
   335                               (encoding_of computer) cache_patterns raw_thms
   336 	val _ = (ref_of computer) := SOME c	
   336         val _ = (ref_of computer) := SOME c     
   337     in
   337     in
   338 	()
   338         ()
   339     end
   339     end
   340 
   340 
   341 fun update computer raw_thms = update_with_cache computer [] raw_thms
   341 fun update computer raw_thms = update_with_cache computer [] raw_thms
   342 
   342 
   343 fun discard computer =
   343 fun discard computer =
   344     let
   344     let
   345 	val _ = 
   345         val _ = 
   346 	    case prog_of computer of
   346             case prog_of computer of
   347 		ProgBarras p => AM_Interpreter.discard p
   347                 ProgBarras p => AM_Interpreter.discard p
   348 	      | ProgBarrasC p => AM_Compiler.discard p
   348               | ProgBarrasC p => AM_Compiler.discard p
   349 	      | ProgHaskell p => AM_GHC.discard p
   349               | ProgHaskell p => AM_GHC.discard p
   350 	      | ProgSML p => AM_SML.discard p
   350               | ProgSML p => AM_SML.discard p
   351 	val _ = (ref_of computer) := NONE
   351         val _ = (ref_of computer) := NONE
   352     in
   352     in
   353 	()
   353         ()
   354     end 
   354     end 
   355 					      
   355                                               
   356 fun runprog (ProgBarras p) = AM_Interpreter.run p
   356 fun runprog (ProgBarras p) = AM_Interpreter.run p
   357   | runprog (ProgBarrasC p) = AM_Compiler.run p
   357   | runprog (ProgBarrasC p) = AM_Compiler.run p
   358   | runprog (ProgHaskell p) = AM_GHC.run p
   358   | runprog (ProgHaskell p) = AM_GHC.run p
   359   | runprog (ProgSML p) = AM_SML.run p	  
   359   | runprog (ProgSML p) = AM_SML.run p    
   360 
   360 
   361 (* ------------------------------------------------------------------------------------- *)
   361 (* ------------------------------------------------------------------------------------- *)
   362 (* An oracle for exporting theorems; must only be accessible from inside this structure! *)
   362 (* An oracle for exporting theorems; must only be accessible from inside this structure! *)
   363 (* ------------------------------------------------------------------------------------- *)
   363 (* ------------------------------------------------------------------------------------- *)
   364 
   364 
   375 
   375 
   376 fun merge_shyps shyps1 shyps2 = Sorttab.keys (add_shyps shyps2 (add_shyps shyps1 Sorttab.empty))
   376 fun merge_shyps shyps1 shyps2 = Sorttab.keys (add_shyps shyps2 (add_shyps shyps1 Sorttab.empty))
   377 
   377 
   378 fun export_oracle (thy, ExportThm (hyps, shyps, prop)) =
   378 fun export_oracle (thy, ExportThm (hyps, shyps, prop)) =
   379     let
   379     let
   380 	val shyptab = add_shyps shyps Sorttab.empty
   380         val shyptab = add_shyps shyps Sorttab.empty
   381 	fun delete s shyptab = Sorttab.delete s shyptab handle Sorttab.UNDEF _ => shyptab
   381         fun delete s shyptab = Sorttab.delete s shyptab handle Sorttab.UNDEF _ => shyptab
   382 	fun delete_term t shyptab = fold delete (Sorts.insert_term t []) shyptab
   382         fun delete_term t shyptab = fold delete (Sorts.insert_term t []) shyptab
   383 	fun has_witness s = not (null (Sign.witness_sorts thy [] [s]))
   383         fun has_witness s = not (null (Sign.witness_sorts thy [] [s]))
   384 	val shyptab = fold Sorttab.delete (filter has_witness (Sorttab.keys (shyptab))) shyptab
   384         val shyptab = fold Sorttab.delete (filter has_witness (Sorttab.keys (shyptab))) shyptab
   385 	val shyps = if Sorttab.is_empty shyptab then [] else Sorttab.keys (fold delete_term (prop::hyps) shyptab)
   385         val shyps = if Sorttab.is_empty shyptab then [] else Sorttab.keys (fold delete_term (prop::hyps) shyptab)
   386 	val _ = if not (null shyps) then raise Compute ("dangling sort hypotheses: "^(makestring shyps)) else ()
   386         val _ = if not (null shyps) then raise Compute ("dangling sort hypotheses: "^(makestring shyps)) else ()
   387     in
   387     in
   388 	fold_rev (fn hyp => fn p => Logic.mk_implies (hyp, p)) hyps prop
   388         fold_rev (fn hyp => fn p => Logic.mk_implies (hyp, p)) hyps prop
   389     end
   389     end
   390   | export_oracle _ = raise Match
   390   | export_oracle _ = raise Match
   391 
   391 
   392 val setup_compute = (fn thy => Theory.add_oracle ("compute", export_oracle) thy)
   392 val setup_compute = (fn thy => Theory.add_oracle ("compute", export_oracle) thy)
   393 
   393 
   394 fun export_thm thy hyps shyps prop =
   394 fun export_thm thy hyps shyps prop =
   395     let
   395     let
   396 	val th = invoke_oracle_i thy "Compute_Oracle.compute" (thy, ExportThm (hyps, shyps, prop))
   396         val th = invoke_oracle_i thy "Compute_Oracle.compute" (thy, ExportThm (hyps, shyps, prop))
   397 	val hyps = map (fn h => assume (cterm_of thy h)) hyps
   397         val hyps = map (fn h => assume (cterm_of thy h)) hyps
   398     in
   398     in
   399 	fold (fn h => fn p => implies_elim p h) hyps th 
   399         fold (fn h => fn p => implies_elim p h) hyps th 
   400     end
   400     end
   401 	
   401         
   402 (* --------- Rewrite ----------- *)
   402 (* --------- Rewrite ----------- *)
   403 
   403 
   404 fun rewrite computer ct =
   404 fun rewrite computer ct =
   405     let
   405     let
   406 	val {t=t',T=ty,thy=thy,...} = rep_cterm ct
   406         val thy = Thm.theory_of_cterm ct
   407 	val _ = Theory.assert_super (theory_of computer) thy
   407         val {t=t',T=ty,...} = rep_cterm ct
   408 	val naming = naming_of computer
   408         val _ = Theory.assert_super (theory_of computer) thy
       
   409         val naming = naming_of computer
   409         val (encoding, t) = remove_types (encoding_of computer) t'
   410         val (encoding, t) = remove_types (encoding_of computer) t'
   410 	(*val _ = if (!print_encoding) then writeln (makestring ("encoding: ",Encode.fold (fn x => fn s => x::s) encoding [])) else ()*)
   411         (*val _ = if (!print_encoding) then writeln (makestring ("encoding: ",Encode.fold (fn x => fn s => x::s) encoding [])) else ()*)
   411         val t = runprog (prog_of computer) t
   412         val t = runprog (prog_of computer) t
   412         val t = infer_types naming encoding ty t
   413         val t = infer_types naming encoding ty t
   413 	val eq = Logic.mk_equals (t', t)
   414         val eq = Logic.mk_equals (t', t)
   414     in
   415     in
   415         export_thm thy (hyps_of computer) (Sorttab.keys (shyptab_of computer)) eq
   416         export_thm thy (hyps_of computer) (Sorttab.keys (shyptab_of computer)) eq
   416     end
   417     end
   417 
   418 
   418 (* --------- Simplify ------------ *)
   419 (* --------- Simplify ------------ *)
   419 
   420 
   420 datatype prem = EqPrem of AbstractMachine.term * AbstractMachine.term * Term.typ * int 
   421 datatype prem = EqPrem of AbstractMachine.term * AbstractMachine.term * Term.typ * int 
   421 	      | Prem of AbstractMachine.term
   422               | Prem of AbstractMachine.term
   422 datatype theorem = Theorem of theory_ref * unit ref * (int * typ) Symtab.table * (AbstractMachine.term option) Inttab.table  
   423 datatype theorem = Theorem of theory_ref * unit ref * (int * typ) Symtab.table * (AbstractMachine.term option) Inttab.table  
   423                * prem list * AbstractMachine.term * term list * sort list
   424                * prem list * AbstractMachine.term * term list * sort list
   424 
   425 
   425 
   426 
   426 exception ParamSimplify of computer * theorem
   427 exception ParamSimplify of computer * theorem
   437     fun collect_vars (Abs (_, _, t)) tab = collect_vars t tab
   438     fun collect_vars (Abs (_, _, t)) tab = collect_vars t tab
   438       | collect_vars (a $ b) tab = collect_vars b (collect_vars a tab)
   439       | collect_vars (a $ b) tab = collect_vars b (collect_vars a tab)
   439       | collect_vars (Const _) tab = tab
   440       | collect_vars (Const _) tab = tab
   440       | collect_vars (Free _) tab = tab
   441       | collect_vars (Free _) tab = tab
   441       | collect_vars (Var ((s, i), ty)) tab = 
   442       | collect_vars (Var ((s, i), ty)) tab = 
   442 	    if List.find (fn x => x=s) vars = NONE then 
   443             if List.find (fn x => x=s) vars = NONE then 
   443 		tab
   444                 tab
   444 	    else		
   445             else                
   445 		(case Symtab.lookup tab s of
   446                 (case Symtab.lookup tab s of
   446 		     SOME ((s',i'),ty') => 
   447                      SOME ((s',i'),ty') => 
   447 	             if s' <> s orelse i' <> i orelse ty <> ty' then 
   448                      if s' <> s orelse i' <> i orelse ty <> ty' then 
   448 			 raise Compute ("make_theorem: variable name '"^s^"' is not unique")
   449                          raise Compute ("make_theorem: variable name '"^s^"' is not unique")
   449 		     else 
   450                      else 
   450 			 tab
   451                          tab
   451 		   | NONE => Symtab.update (s, ((s, i), ty)) tab)
   452                    | NONE => Symtab.update (s, ((s, i), ty)) tab)
   452     val vartab = collect_vars prop Symtab.empty 
   453     val vartab = collect_vars prop Symtab.empty 
   453     fun encodevar (s, t as (_, ty)) (encoding, tab) = 
   454     fun encodevar (s, t as (_, ty)) (encoding, tab) = 
   454 	let
   455         let
   455 	    val (x, encoding) = Encode.insert (Var t) encoding
   456             val (x, encoding) = Encode.insert (Var t) encoding
   456 	in
   457         in
   457 	    (encoding, Symtab.update (s, (x, ty)) tab)
   458             (encoding, Symtab.update (s, (x, ty)) tab)
   458 	end
   459         end
   459     val (encoding, vartab) = Symtab.fold encodevar vartab (encoding, Symtab.empty)  					 	       
   460     val (encoding, vartab) = Symtab.fold encodevar vartab (encoding, Symtab.empty)                                                     
   460     val varsubst = Inttab.make (map (fn (s, (x, _)) => (x, NONE)) (Symtab.dest vartab))
   461     val varsubst = Inttab.make (map (fn (s, (x, _)) => (x, NONE)) (Symtab.dest vartab))
   461 
   462 
   462     (* make the premises and the conclusion *)
   463     (* make the premises and the conclusion *)
   463     fun mk_prem encoding t = 
   464     fun mk_prem encoding t = 
   464 	(let
   465         (let
   465 	     val (a, b) = Logic.dest_equals t
   466              val (a, b) = Logic.dest_equals t
   466 	     val ty = type_of a
   467              val ty = type_of a
   467 	     val (encoding, a) = remove_types encoding a
   468              val (encoding, a) = remove_types encoding a
   468 	     val (encoding, b) = remove_types encoding b
   469              val (encoding, b) = remove_types encoding b
   469 	     val (eq, encoding) = Encode.insert (Const ("==", ty --> ty --> @{typ "prop"})) encoding 
   470              val (eq, encoding) = Encode.insert (Const ("==", ty --> ty --> @{typ "prop"})) encoding 
   470 	 in
   471          in
   471 	     (encoding, EqPrem (a, b, ty, eq))
   472              (encoding, EqPrem (a, b, ty, eq))
   472 	 end handle TERM _ => let val (encoding, t) = remove_types encoding t in (encoding, Prem t) end)
   473          end handle TERM _ => let val (encoding, t) = remove_types encoding t in (encoding, Prem t) end)
   473     val (encoding, prems) = 
   474     val (encoding, prems) = 
   474 	(fold_rev (fn t => fn (encoding, l) => 
   475         (fold_rev (fn t => fn (encoding, l) => 
   475 	    case mk_prem encoding t  of 
   476             case mk_prem encoding t  of 
   476                 (encoding, t) => (encoding, t::l)) (Logic.strip_imp_prems prop) (encoding, []))
   477                 (encoding, t) => (encoding, t::l)) (Logic.strip_imp_prems prop) (encoding, []))
   477     val (encoding, concl) = remove_types encoding (Logic.strip_imp_concl prop)
   478     val (encoding, concl) = remove_types encoding (Logic.strip_imp_concl prop)
   478     val _ = set_encoding computer encoding
   479     val _ = set_encoding computer encoding
   479 in
   480 in
   480     Theorem (Theory.check_thy (theory_of_thm th), stamp_of computer, vartab, varsubst, 
   481     Theorem (Theory.check_thy (theory_of_thm th), stamp_of computer, vartab, varsubst, 
   481 	     prems, concl, hyps, shyps)
   482              prems, concl, hyps, shyps)
   482 end
   483 end
   483     
   484     
   484 fun theory_of_theorem (Theorem (rthy,_,_,_,_,_,_,_)) = Theory.deref rthy
   485 fun theory_of_theorem (Theorem (rthy,_,_,_,_,_,_,_)) = Theory.deref rthy
   485 fun update_theory thy (Theorem (_,p0,p1,p2,p3,p4,p5,p6)) =
   486 fun update_theory thy (Theorem (_,p0,p1,p2,p3,p4,p5,p6)) =
   486     Theorem (Theory.check_thy thy,p0,p1,p2,p3,p4,p5,p6)
   487     Theorem (Theory.check_thy thy,p0,p1,p2,p3,p4,p5,p6)
   496 fun shyps_of_theorem (Theorem (_,_,_,_,_,_,_,shyps)) = shyps
   497 fun shyps_of_theorem (Theorem (_,_,_,_,_,_,_,shyps)) = shyps
   497 fun update_shyps shyps (Theorem (p0,p1,p2,p3,p4,p5,p6,_)) = Theorem (p0,p1,p2,p3,p4,p5,p6,shyps)
   498 fun update_shyps shyps (Theorem (p0,p1,p2,p3,p4,p5,p6,_)) = Theorem (p0,p1,p2,p3,p4,p5,p6,shyps)
   498 
   499 
   499 fun check_compatible computer th s = 
   500 fun check_compatible computer th s = 
   500     if stamp_of computer <> stamp_of_theorem th then
   501     if stamp_of computer <> stamp_of_theorem th then
   501 	raise Compute (s^": computer and theorem are incompatible")
   502         raise Compute (s^": computer and theorem are incompatible")
   502     else ()
   503     else ()
   503 
   504 
   504 fun instantiate computer insts th =
   505 fun instantiate computer insts th =
   505 let
   506 let
   506     val _ = check_compatible computer th
   507     val _ = check_compatible computer th
   509 
   510 
   510     val vartab = vartab_of_theorem th
   511     val vartab = vartab_of_theorem th
   511 
   512 
   512     fun rewrite computer t =
   513     fun rewrite computer t =
   513     let  
   514     let  
   514 	val naming = naming_of computer
   515         val naming = naming_of computer
   515         val (encoding, t) = remove_types (encoding_of computer) t
   516         val (encoding, t) = remove_types (encoding_of computer) t
   516         val t = runprog (prog_of computer) t
   517         val t = runprog (prog_of computer) t
   517 	val _ = set_encoding computer encoding
   518         val _ = set_encoding computer encoding
   518     in
   519     in
   519         t
   520         t
   520     end
   521     end
   521 
   522 
   522     fun assert_varfree vs t = 
   523     fun assert_varfree vs t = 
   523 	if AbstractMachine.forall_consts (fn x => Inttab.lookup vs x = NONE) t then
   524         if AbstractMachine.forall_consts (fn x => Inttab.lookup vs x = NONE) t then
   524 	    ()
   525             ()
   525 	else
   526         else
   526 	    raise Compute "instantiate: assert_varfree failed"
   527             raise Compute "instantiate: assert_varfree failed"
   527 
   528 
   528     fun assert_closed t =
   529     fun assert_closed t =
   529 	if AbstractMachine.closed t then
   530         if AbstractMachine.closed t then
   530 	    ()
   531             ()
   531 	else 
   532         else 
   532 	    raise Compute "instantiate: not a closed term"
   533             raise Compute "instantiate: not a closed term"
   533 
   534 
   534     fun compute_inst (s, ct) vs =
   535     fun compute_inst (s, ct) vs =
   535 	let
   536         let
   536 	    val _ = Theory.assert_super (theory_of_cterm ct) thy
   537             val _ = Theory.assert_super (theory_of_cterm ct) thy
   537 	    val ty = typ_of (ctyp_of_term ct) 
   538             val ty = typ_of (ctyp_of_term ct) 
   538 	in	    
   539         in          
   539 	    (case Symtab.lookup vartab s of 
   540             (case Symtab.lookup vartab s of 
   540 		 NONE => raise Compute ("instantiate: variable '"^s^"' not found in theorem")
   541                  NONE => raise Compute ("instantiate: variable '"^s^"' not found in theorem")
   541 	       | SOME (x, ty') => 
   542                | SOME (x, ty') => 
   542 		 (case Inttab.lookup vs x of 
   543                  (case Inttab.lookup vs x of 
   543 		      SOME (SOME _) => raise Compute ("instantiate: variable '"^s^"' has already been instantiated")
   544                       SOME (SOME _) => raise Compute ("instantiate: variable '"^s^"' has already been instantiated")
   544 		    | SOME NONE => 
   545                     | SOME NONE => 
   545 		      if ty <> ty' then 
   546                       if ty <> ty' then 
   546 			  raise Compute ("instantiate: wrong type for variable '"^s^"'")
   547                           raise Compute ("instantiate: wrong type for variable '"^s^"'")
   547 		      else
   548                       else
   548 			  let
   549                           let
   549 			      val t = rewrite computer (term_of ct)
   550                               val t = rewrite computer (term_of ct)
   550 			      val _ = assert_varfree vs t 
   551                               val _ = assert_varfree vs t 
   551 			      val _ = assert_closed t
   552                               val _ = assert_closed t
   552 			  in
   553                           in
   553 			      Inttab.update (x, SOME t) vs
   554                               Inttab.update (x, SOME t) vs
   554 			  end
   555                           end
   555 		    | NONE => raise Compute "instantiate: internal error"))
   556                     | NONE => raise Compute "instantiate: internal error"))
   556 	end
   557         end
   557 
   558 
   558     val vs = fold compute_inst insts (varsubst_of_theorem th)
   559     val vs = fold compute_inst insts (varsubst_of_theorem th)
   559 in
   560 in
   560     update_varsubst vs th
   561     update_varsubst vs th
   561 end
   562 end
   562 
   563 
   563 fun match_aterms subst =
   564 fun match_aterms subst =
   564     let	
   565     let 
   565 	exception no_match
   566         exception no_match
   566 	open AbstractMachine
   567         open AbstractMachine
   567 	fun match subst (b as (Const c)) a = 
   568         fun match subst (b as (Const c)) a = 
   568 	    if a = b then subst
   569             if a = b then subst
   569 	    else 
   570             else 
   570 		(case Inttab.lookup subst c of 
   571                 (case Inttab.lookup subst c of 
   571 		     SOME (SOME a') => if a=a' then subst else raise no_match
   572                      SOME (SOME a') => if a=a' then subst else raise no_match
   572 		   | SOME NONE => if AbstractMachine.closed a then 
   573                    | SOME NONE => if AbstractMachine.closed a then 
   573 				      Inttab.update (c, SOME a) subst 
   574                                       Inttab.update (c, SOME a) subst 
   574 				  else raise no_match
   575                                   else raise no_match
   575 		   | NONE => raise no_match)
   576                    | NONE => raise no_match)
   576 	  | match subst (b as (Var _)) a = if a=b then subst else raise no_match
   577           | match subst (b as (Var _)) a = if a=b then subst else raise no_match
   577 	  | match subst (App (u, v)) (App (u', v')) = match (match subst u u') v v'
   578           | match subst (App (u, v)) (App (u', v')) = match (match subst u u') v v'
   578 	  | match subst (Abs u) (Abs u') = match subst u u'
   579           | match subst (Abs u) (Abs u') = match subst u u'
   579 	  | match subst _ _ = raise no_match
   580           | match subst _ _ = raise no_match
   580     in
   581     in
   581 	fn b => fn a => (SOME (match subst b a) handle no_match => NONE)
   582         fn b => fn a => (SOME (match subst b a) handle no_match => NONE)
   582     end
   583     end
   583 
   584 
   584 fun apply_subst vars_allowed subst =
   585 fun apply_subst vars_allowed subst =
   585     let
   586     let
   586 	open AbstractMachine
   587         open AbstractMachine
   587 	fun app (t as (Const c)) = 
   588         fun app (t as (Const c)) = 
   588 	    (case Inttab.lookup subst c of 
   589             (case Inttab.lookup subst c of 
   589 		 NONE => t 
   590                  NONE => t 
   590 	       | SOME (SOME t) => Computed t
   591                | SOME (SOME t) => Computed t
   591 	       | SOME NONE => if vars_allowed then t else raise Compute "apply_subst: no vars allowed")
   592                | SOME NONE => if vars_allowed then t else raise Compute "apply_subst: no vars allowed")
   592 	  | app (t as (Var _)) = t
   593           | app (t as (Var _)) = t
   593 	  | app (App (u, v)) = App (app u, app v)
   594           | app (App (u, v)) = App (app u, app v)
   594 	  | app (Abs m) = Abs (app m)
   595           | app (Abs m) = Abs (app m)
   595     in
   596     in
   596 	app
   597         app
   597     end
   598     end
   598 
   599 
   599 fun splicein n l L = List.take (L, n) @ l @ List.drop (L, n+1)
   600 fun splicein n l L = List.take (L, n) @ l @ List.drop (L, n+1)
   600 
   601 
   601 fun evaluate_prem computer prem_no th =
   602 fun evaluate_prem computer prem_no th =
   602 let
   603 let
   603     val _ = check_compatible computer th
   604     val _ = check_compatible computer th
   604     val prems = prems_of_theorem th
   605     val prems = prems_of_theorem th
   605     val varsubst = varsubst_of_theorem th
   606     val varsubst = varsubst_of_theorem th
   606     fun run vars_allowed t = 
   607     fun run vars_allowed t = 
   607 	runprog (prog_of computer) (apply_subst vars_allowed varsubst t)
   608         runprog (prog_of computer) (apply_subst vars_allowed varsubst t)
   608 in
   609 in
   609     case List.nth (prems, prem_no) of
   610     case List.nth (prems, prem_no) of
   610 	Prem _ => raise Compute "evaluate_prem: no equality premise"
   611         Prem _ => raise Compute "evaluate_prem: no equality premise"
   611       | EqPrem (a, b, ty, _) => 	
   612       | EqPrem (a, b, ty, _) =>         
   612 	let
   613         let
   613 	    val a' = run false a
   614             val a' = run false a
   614 	    val b' = run true b
   615             val b' = run true b
   615 	in
   616         in
   616 	    case match_aterms varsubst b' a' of
   617             case match_aterms varsubst b' a' of
   617 		NONE => 
   618                 NONE => 
   618 		let
   619                 let
   619 		    fun mk s = makestring (infer_types (naming_of computer) (encoding_of computer) ty s)
   620                     fun mk s = makestring (infer_types (naming_of computer) (encoding_of computer) ty s)
   620 		    val left = "computed left side: "^(mk a')
   621                     val left = "computed left side: "^(mk a')
   621 		    val right = "computed right side: "^(mk b')
   622                     val right = "computed right side: "^(mk b')
   622 		in
   623                 in
   623 		    raise Compute ("evaluate_prem: cannot assign computed left to right hand side\n"^left^"\n"^right^"\n")
   624                     raise Compute ("evaluate_prem: cannot assign computed left to right hand side\n"^left^"\n"^right^"\n")
   624 		end
   625                 end
   625 	      | SOME varsubst => 
   626               | SOME varsubst => 
   626 		update_prems (splicein prem_no [] prems) (update_varsubst varsubst th)
   627                 update_prems (splicein prem_no [] prems) (update_varsubst varsubst th)
   627 	end
   628         end
   628 end
   629 end
   629 
   630 
   630 fun prem2term (Prem t) = t
   631 fun prem2term (Prem t) = t
   631   | prem2term (EqPrem (a,b,_,eq)) = 
   632   | prem2term (EqPrem (a,b,_,eq)) = 
   632     AbstractMachine.App (AbstractMachine.App (AbstractMachine.Const eq, a), b)
   633     AbstractMachine.App (AbstractMachine.App (AbstractMachine.Const eq, a), b)
   633 
   634 
   634 fun modus_ponens computer prem_no th' th = 
   635 fun modus_ponens computer prem_no th' th = 
   635 let
   636 let
   636     val _ = check_compatible computer th
   637     val _ = check_compatible computer th
   637     val thy = 
   638     val thy = 
   638 	let
   639         let
   639 	    val thy1 = theory_of_theorem th
   640             val thy1 = theory_of_theorem th
   640 	    val thy2 = theory_of_thm th'
   641             val thy2 = theory_of_thm th'
   641 	in
   642         in
   642 	    if Context.subthy (thy1, thy2) then thy2 
   643             if Context.subthy (thy1, thy2) then thy2 
   643 	    else if Context.subthy (thy2, thy1) then thy1 else
   644             else if Context.subthy (thy2, thy1) then thy1 else
   644 	    raise Compute "modus_ponens: theorems are not compatible with each other"
   645             raise Compute "modus_ponens: theorems are not compatible with each other"
   645 	end 
   646         end 
   646     val th' = make_theorem computer th' []
   647     val th' = make_theorem computer th' []
   647     val varsubst = varsubst_of_theorem th
   648     val varsubst = varsubst_of_theorem th
   648     fun run vars_allowed t =
   649     fun run vars_allowed t =
   649 	runprog (prog_of computer) (apply_subst vars_allowed varsubst t)
   650         runprog (prog_of computer) (apply_subst vars_allowed varsubst t)
   650     val prems = prems_of_theorem th
   651     val prems = prems_of_theorem th
   651     val prem = run true (prem2term (List.nth (prems, prem_no)))
   652     val prem = run true (prem2term (List.nth (prems, prem_no)))
   652     val concl = run false (concl_of_theorem th')    
   653     val concl = run false (concl_of_theorem th')    
   653 in
   654 in
   654     case match_aterms varsubst prem concl of
   655     case match_aterms varsubst prem concl of
   655 	NONE => raise Compute "modus_ponens: conclusion does not match premise"
   656         NONE => raise Compute "modus_ponens: conclusion does not match premise"
   656       | SOME varsubst =>
   657       | SOME varsubst =>
   657 	let
   658         let
   658 	    val th = update_varsubst varsubst th
   659             val th = update_varsubst varsubst th
   659 	    val th = update_prems (splicein prem_no (prems_of_theorem th') prems) th
   660             val th = update_prems (splicein prem_no (prems_of_theorem th') prems) th
   660 	    val th = update_hyps (merge_hyps (hyps_of_theorem th) (hyps_of_theorem th')) th
   661             val th = update_hyps (merge_hyps (hyps_of_theorem th) (hyps_of_theorem th')) th
   661 	    val th = update_shyps (merge_shyps (shyps_of_theorem th) (shyps_of_theorem th')) th
   662             val th = update_shyps (merge_shyps (shyps_of_theorem th) (shyps_of_theorem th')) th
   662 	in
   663         in
   663 	    update_theory thy th
   664             update_theory thy th
   664 	end
   665         end
   665 end
   666 end
   666                      
   667                      
   667 fun simplify computer th =
   668 fun simplify computer th =
   668 let
   669 let
   669     val _ = check_compatible computer th
   670     val _ = check_compatible computer th