src/Pure/Tools/compute.ML
author wenzelm
Wed, 13 Jul 2005 16:07:30 +0200
changeset 16809 8ca51a846576
parent 16781 663235466562
child 16851 551462cc8ca0
permissions -rw-r--r--
export eq_brl;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16781
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
     1
(*  Title:      Pure/Tools/compute.ML
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
     2
    ID:         $Id$
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
     3
    Author:     Steven Obua
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
     4
*)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
     5
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
     6
signature COMPUTE = sig
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
     7
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
     8
    type computer
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
     9
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    10
    exception Make of string
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    11
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    12
    val basic_make : theory -> thm list -> computer
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    13
    val make : theory -> thm list -> computer
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    14
    
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    15
    val compute : computer -> (int -> string) -> cterm -> term
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    16
    val theory_of : computer -> theory
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    17
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    18
    val rewrite_param : computer -> (int -> string) -> cterm -> thm
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    19
    val rewrite : computer -> cterm -> thm
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    20
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    21
end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    22
			     
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    23
structure Compute :> COMPUTE = struct
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    24
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    25
exception Internal of string; (* this exception is only thrown if there is a bug *)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    26
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    27
exception Make of string;
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    28
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    29
fun is_mono_typ (Type (_, list)) = List.all is_mono_typ list
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    30
  | is_mono_typ _ = false
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    31
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    32
fun is_mono_term (Const (_, t)) = is_mono_typ t
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    33
  | is_mono_term (Var (_, t)) = is_mono_typ t
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    34
  | is_mono_term (Free (_, t)) = is_mono_typ t
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    35
  | is_mono_term (Bound _) = true
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    36
  | is_mono_term (a $ b) = is_mono_term a andalso is_mono_term b
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    37
  | is_mono_term (Abs (_, ty, t)) = is_mono_typ ty andalso is_mono_term t
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    38
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    39
structure TermTab = Termtab
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    40
structure AMTermTab = TableFun (type key = AbstractMachine.term val ord = AM_Util.term_ord)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    41
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    42
fun add x y = Int.+ (x, y)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    43
fun inc x = Int.+ (x, 1)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    44
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    45
exception Mono of term;
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    46
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    47
val remove_types = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    48
    let	
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    49
	fun remove_types_var table invtable ccount vcount ldepth t =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    50
	    (case TermTab.lookup (table, t) of
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    51
		 NONE => 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    52
		 let 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    53
		     val a = AbstractMachine.Var vcount 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    54
		 in	    
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    55
		     (TermTab.update ((t, a), table), 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    56
		      AMTermTab.update ((a, t), invtable),
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    57
		      ccount,
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    58
		      inc vcount,
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    59
		      AbstractMachine.Var (add vcount ldepth))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    60
		 end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    61
	       | SOME (AbstractMachine.Var v) =>
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    62
		 (table, invtable, ccount, vcount, AbstractMachine.Var (add v ldepth))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    63
	       | SOME _ => raise (Internal "remove_types_var: lookup should be a var"))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    64
	    
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    65
	fun remove_types_const table invtable ccount vcount ldepth t =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    66
	    (case TermTab.lookup (table, t) of 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    67
		 NONE => 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    68
		 let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    69
		     val a = AbstractMachine.Const ccount
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    70
		 in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    71
		     (TermTab.update ((t, a), table),
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    72
		      AMTermTab.update ((a, t), invtable),
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    73
		      inc ccount,
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    74
		      vcount,
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    75
		      a)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    76
		 end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    77
	       | SOME (c as AbstractMachine.Const _) => 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    78
		 (table, invtable, ccount, vcount, c)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    79
	       | SOME _ => raise (Internal "remove_types_const: lookup should be a const"))			
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    80
	    
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    81
	fun remove_types table invtable ccount vcount ldepth t = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    82
	    case t of
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    83
		Var (_, ty) => 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    84
                  if is_mono_typ ty then remove_types_var table invtable ccount vcount ldepth t 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    85
                  else raise (Mono t)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    86
	      | Free (_, ty) => 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    87
                  if is_mono_typ ty then remove_types_var table invtable ccount vcount ldepth t 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    88
                  else raise (Mono t)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    89
	      | Const (_, ty) => 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    90
                  if is_mono_typ ty then remove_types_const table invtable ccount vcount ldepth t 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    91
                  else raise (Mono t)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    92
	      | Abs (_, ty, t') => 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    93
		if is_mono_typ ty then
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    94
		    let 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    95
			val (table, invtable, ccount, vcount, t') = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    96
			    remove_types table invtable ccount vcount (inc ldepth) t'  
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    97
		    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    98
			(table, invtable, ccount, vcount, AbstractMachine.Abs t')
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
    99
		    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   100
		else
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   101
		    raise (Mono t)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   102
	      | a $ b => 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   103
		let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   104
		    val (table, invtable, ccount, vcount, a) =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   105
			remove_types table invtable ccount vcount ldepth a
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   106
		    val (table, invtable, ccount, vcount, b) =  
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   107
			remove_types table invtable ccount vcount ldepth b
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   108
		in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   109
		    (table, invtable, ccount, vcount, AbstractMachine.App (a,b))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   110
		end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   111
	      | Bound b => (table, invtable, ccount, vcount, AbstractMachine.Var b)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   112
    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   113
     fn (table, invtable, ccount, vcount) => remove_types table invtable ccount vcount 0
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   114
    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   115
    
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   116
fun infer_types naming =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   117
    let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   118
	fun infer_types invtable ldepth bounds ty (AbstractMachine.Var v) =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   119
	    if v < ldepth then (Bound v, List.nth (bounds, v)) else
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   120
	    (case AMTermTab.lookup (invtable, AbstractMachine.Var (v-ldepth)) of
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   121
		 SOME (t as Var (_, ty)) => (t, ty)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   122
	       | SOME (t as Free (_, ty)) => (t, ty)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   123
	       | _ => raise (Internal "infer_types: lookup should deliver Var or Free"))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   124
	  | infer_types invtable ldepth _ ty (c as AbstractMachine.Const _) =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   125
	    (case AMTermTab.lookup (invtable, c) of
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   126
		 SOME (c as Const (_, ty)) => (c, ty)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   127
	       | _ => raise (Internal "infer_types: lookup should deliver Const"))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   128
	  | infer_types invtable ldepth bounds (n,ty) (AbstractMachine.App (a, b)) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   129
	    let 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   130
		val (a, aty) = infer_types invtable ldepth bounds (n+1, ty) a
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   131
		val (adom, arange) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   132
		    case aty of 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   133
			Type ("fun", [dom, range]) => (dom, range)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   134
		      | _ => raise (Internal "infer_types: function type expected")
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   135
		val (b, bty) = infer_types invtable ldepth bounds (0, adom) b
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   136
	    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   137
		(a $ b, arange)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   138
	    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   139
	  | infer_types invtable ldepth bounds (0, ty as Type ("fun", [dom, range])) (AbstractMachine.Abs m) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   140
	    let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   141
		val (m, _) = infer_types invtable (ldepth+1) (dom::bounds) (0, range) m
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   142
	    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   143
		(Abs (naming ldepth, dom, m), ty)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   144
	    end		
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   145
	  | infer_types invtable ldepth bounds ty (AbstractMachine.Abs m) =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   146
	    raise (Internal "infer_types: cannot infer type of abstraction")
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   147
		  
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   148
	fun infer invtable ty term = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   149
	    let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   150
		val (term', _) = infer_types invtable 0 [] (0, ty) term
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   151
	    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   152
		term'
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   153
	    end    
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   154
    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   155
	infer
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   156
    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   157
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   158
structure Inttab = TableFun (type key = int val ord=int_ord);
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   159
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   160
type computer = theory_ref * (AbstractMachine.term TermTab.table * term AMTermTab.table * int * 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   161
                              AbstractMachine.program)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   162
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   163
fun rthy_of_thm th = Theory.self_ref (theory_of_thm th)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   164
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   165
fun basic_make thy ths = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   166
    let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   167
        val _ = List.foldl (fn (th, _) => Theory.assert_super (theory_of_thm th) thy) thy ths
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   168
        val rthy = Theory.self_ref thy
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   169
	 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   170
	fun thm2rule table invtable ccount th = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   171
	    let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   172
		val prop = Drule.plain_prop_of (transfer thy th)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   173
		val _ = if Logic.is_equals prop then () else raise (Make "theorems must be equations")
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   174
		val (a, b) = Logic.dest_equals prop
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   175
			    
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   176
		val (table, invtable, ccount, vcount, prop) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   177
		    remove_types (table, invtable, ccount, 0) (a$b) 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   178
		    handle Mono _ => raise (Make "no type variables allowed")
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   179
		val (left, right) = (case prop of AbstractMachine.App x => x | _ => raise (Internal "make: remove_types should deliver application"))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   180
							       
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   181
		fun make_pattern table invtable n vars (var as AbstractMachine.Var v) =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   182
		    let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   183
			val var' = valOf (AMTermTab.lookup (invtable, var))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   184
			val table = TermTab.delete var' table
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   185
			val invtable = AMTermTab.delete var invtable
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   186
			val vars = Inttab.update_new ((v, n), vars) handle Inttab.DUP _ => raise (Make "no duplicate variable in pattern allowed")
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   187
		    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   188
			(table, invtable, n+1, vars, AbstractMachine.PVar)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   189
		    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   190
		  | make_pattern table invtable n vars (AbstractMachine.Abs _) = raise (Make "no lambda abstractions allowed in pattern")
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   191
		  | make_pattern table invtable n vars (AbstractMachine.Const c) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   192
		    (table, invtable, n, vars, AbstractMachine.PConst (c, []))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   193
		  | make_pattern table invtable n vars (AbstractMachine.App (a, b)) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   194
		    let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   195
			val (table, invtable, n, vars, pa) = make_pattern table invtable n vars a
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   196
			val (table, invtable, n, vars, pb) = make_pattern table invtable n vars b
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   197
		    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   198
			case pa of 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   199
			    AbstractMachine.PVar => raise (Make "patterns may not start with a variable")
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   200
			  | AbstractMachine.PConst (c, args) => (table, invtable, n, vars, AbstractMachine.PConst (c, args@[pb]))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   201
		    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   202
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   203
		val (table, invtable, vcount, vars, pattern) = make_pattern table invtable 0 Inttab.empty left
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   204
		val _ = (case pattern of 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   205
			     AbstractMachine.PVar => raise (Make "patterns may not start with a variable") 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   206
			   | _ => ())
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   207
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   208
		(* at this point, there shouldn't be any variables left in table or invtable, only constants *)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   209
													     
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   210
		(* finally, provide a function for renaming the pattern bound variables on the right hand side *)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   211
		fun rename ldepth vars (var as AbstractMachine.Var v) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   212
		    if v < ldepth then var 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   213
		    else (case Inttab.lookup (vars, v-ldepth) of 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   214
			      NONE => raise (Make "new variable on right hand side")
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   215
			    | SOME n => AbstractMachine.Var ((vcount-n-1)+ldepth))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   216
		  | rename ldepth vars (c as AbstractMachine.Const _) = c
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   217
		  | rename ldepth vars (AbstractMachine.App (a, b)) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   218
		    AbstractMachine.App (rename ldepth vars a, rename ldepth vars b)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   219
		  | rename ldepth vars (AbstractMachine.Abs m) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   220
		    AbstractMachine.Abs (rename (ldepth+1) vars m)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   221
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   222
	    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   223
		(table, invtable, ccount, (pattern, rename 0 vars right))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   224
	    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   225
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   226
	val (table, invtable, ccount, rules) = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   227
	    List.foldl (fn (th, (table, invtable, ccount, rules)) => 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   228
			   let 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   229
			       val (table, invtable, ccount, rule) = thm2rule table invtable ccount th
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   230
			   in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   231
			       (table, invtable, ccount, rule::rules)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   232
			   end)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   233
		       (TermTab.empty, AMTermTab.empty, 0, []) (List.rev ths)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   234
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   235
	val prog = AbstractMachine.compile rules
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   236
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   237
    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   238
	(rthy, (table, invtable, ccount, prog))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   239
    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   240
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   241
fun make thy ths = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   242
    let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   243
      val (_, {mk_rews={mk=mk,mk_eq_True=emk, ...},...}) = rep_ss (simpset_of thy)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   244
      fun mk_eq_True th = (case emk th of NONE => [th] | SOME th' => [th, th'])
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   245
      fun app f l = List.concat (map f l)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   246
    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   247
      basic_make thy (app mk (app mk_eq_True ths))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   248
    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   249
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   250
fun compute r naming ct =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   251
    let
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   252
	val {t=t, T=ty, thy=ctthy, ...} = rep_cterm ct
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   253
	val (rthy, (table, invtable, ccount, prog)) = r
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   254
        val thy = Theory.merge (Theory.deref rthy, ctthy)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   255
	val (table, invtable, ccount, vcount, t) = remove_types (table, invtable, ccount, 0) t
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   256
	val t = AbstractMachine.run prog t
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   257
	val t = infer_types naming invtable ty t 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   258
    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   259
	t     
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   260
    end handle Internal s => (writeln ("Internal error: "^s); raise (Internal s))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   261
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   262
fun theory_of (rthy, _) = Theory.deref rthy
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   263
    	
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   264
fun default_naming i = "v_"^(Int.toString i)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   265
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   266
exception Param of computer * (int -> string) * cterm;
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   267
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   268
fun rewrite_param r n ct = 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   269
    let val thy = theory_of_cterm ct in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   270
      invoke_oracle_i thy "Pure.compute" (thy, Param (r, n, ct))
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   271
    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   272
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   273
fun rewrite r ct = rewrite_param r default_naming ct
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   274
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   275
(* setup of the Pure.compute oracle *)
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   276
fun compute_oracle (sg, Param (r, naming, ct)) =
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   277
    let 
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   278
	val _ = Theory.assert_super (theory_of r) sg
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   279
	val t' = compute r naming ct
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   280
    in
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   281
	Logic.mk_equals (term_of ct, t')
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   282
    end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   283
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   284
fun setup_oracle thy = Theory.add_oracle ("compute", compute_oracle) thy
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   285
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   286
val _ = Context.add_setup [setup_oracle]
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   287
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   288
end
663235466562 - introduce Pure/Tools directory
obua
parents:
diff changeset
   289