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