src/HOL/Import/shuffler.ML
changeset 21588 cd0dc678a205
parent 21078 101aefd61aac
child 22578 b0eb5652f210
equal deleted inserted replaced
21587:a3561bfe0ada 21588:cd0dc678a205
    36 
    36 
    37 fun if_debug f x = if !debug then f x else ()
    37 fun if_debug f x = if !debug then f x else ()
    38 val message = if_debug writeln
    38 val message = if_debug writeln
    39 
    39 
    40 (*Prints exceptions readably to users*)
    40 (*Prints exceptions readably to users*)
    41 fun print_sign_exn_unit sign e = 
    41 fun print_sign_exn_unit sign e =
    42   case e of
    42   case e of
    43      THM (msg,i,thms) =>
    43      THM (msg,i,thms) =>
    44 	 (writeln ("Exception THM " ^ string_of_int i ^ " raised:\n" ^ msg);
    44          (writeln ("Exception THM " ^ string_of_int i ^ " raised:\n" ^ msg);
    45 	  List.app print_thm thms)
    45           List.app print_thm thms)
    46    | THEORY (msg,thys) =>
    46    | THEORY (msg,thys) =>
    47 	 (writeln ("Exception THEORY raised:\n" ^ msg);
    47          (writeln ("Exception THEORY raised:\n" ^ msg);
    48 	  List.app (writeln o Context.str_of_thy) thys)
    48           List.app (writeln o Context.str_of_thy) thys)
    49    | TERM (msg,ts) =>
    49    | TERM (msg,ts) =>
    50 	 (writeln ("Exception TERM raised:\n" ^ msg);
    50          (writeln ("Exception TERM raised:\n" ^ msg);
    51 	  List.app (writeln o Sign.string_of_term sign) ts)
    51           List.app (writeln o Sign.string_of_term sign) ts)
    52    | TYPE (msg,Ts,ts) =>
    52    | TYPE (msg,Ts,ts) =>
    53 	 (writeln ("Exception TYPE raised:\n" ^ msg);
    53          (writeln ("Exception TYPE raised:\n" ^ msg);
    54 	  List.app (writeln o Sign.string_of_typ sign) Ts;
    54           List.app (writeln o Sign.string_of_typ sign) Ts;
    55 	  List.app (writeln o Sign.string_of_term sign) ts)
    55           List.app (writeln o Sign.string_of_term sign) ts)
    56    | e => raise e
    56    | e => raise e
    57 
    57 
    58 (*Prints an exception, then fails*)
    58 (*Prints an exception, then fails*)
    59 fun print_sign_exn sign e = (print_sign_exn_unit sign e; raise e)
    59 fun print_sign_exn sign e = (print_sign_exn_unit sign e; raise e)
    60 
    60 
    61 val string_of_thm = Library.setmp print_mode [] string_of_thm;
    61 val string_of_thm = Library.setmp print_mode [] string_of_thm;
    62 val string_of_cterm = Library.setmp print_mode [] string_of_cterm;
    62 val string_of_cterm = Library.setmp print_mode [] string_of_cterm;
    63 
    63 
    64 fun mk_meta_eq th =
    64 fun mk_meta_eq th =
    65     (case concl_of th of
    65     (case concl_of th of
    66 	 Const("Trueprop",_) $ (Const("op =",_) $ _ $ _) => th RS eq_reflection
    66          Const("Trueprop",_) $ (Const("op =",_) $ _ $ _) => th RS eq_reflection
    67        | Const("==",_) $ _ $ _ => th
    67        | Const("==",_) $ _ $ _ => th
    68        | _ => raise THM("Not an equality",0,[th]))
    68        | _ => raise THM("Not an equality",0,[th]))
    69     handle _ => raise THM("Couldn't make meta equality",0,[th])
    69     handle _ => raise THM("Couldn't make meta equality",0,[th])
    70 				   
    70 
    71 fun mk_obj_eq th =
    71 fun mk_obj_eq th =
    72     (case concl_of th of
    72     (case concl_of th of
    73 	 Const("Trueprop",_) $ (Const("op =",_) $ _ $ _) => th
    73          Const("Trueprop",_) $ (Const("op =",_) $ _ $ _) => th
    74        | Const("==",_) $ _ $ _ => th RS meta_eq_to_obj_eq
    74        | Const("==",_) $ _ $ _ => th RS meta_eq_to_obj_eq
    75        | _ => raise THM("Not an equality",0,[th]))
    75        | _ => raise THM("Not an equality",0,[th]))
    76     handle _ => raise THM("Couldn't make object equality",0,[th])
    76     handle _ => raise THM("Couldn't make object equality",0,[th])
    77 
    77 
    78 structure ShuffleDataArgs: THEORY_DATA_ARGS =
    78 structure ShuffleDataArgs: THEORY_DATA_ARGS =
    83 val copy = I
    83 val copy = I
    84 val extend = I
    84 val extend = I
    85 fun merge _ = Library.gen_union Thm.eq_thm
    85 fun merge _ = Library.gen_union Thm.eq_thm
    86 fun print _ thms =
    86 fun print _ thms =
    87     Pretty.writeln (Pretty.big_list "Shuffle theorems:"
    87     Pretty.writeln (Pretty.big_list "Shuffle theorems:"
    88 				    (map Display.pretty_thm thms))
    88                                     (map Display.pretty_thm thms))
    89 end
    89 end
    90 
    90 
    91 structure ShuffleData = TheoryDataFun(ShuffleDataArgs)
    91 structure ShuffleData = TheoryDataFun(ShuffleDataArgs)
    92 
    92 
    93 val weaken =
    93 val weaken =
    94     let
    94     let
    95 	val cert = cterm_of ProtoPure.thy
    95         val cert = cterm_of ProtoPure.thy
    96 	val P = Free("P",propT)
    96         val P = Free("P",propT)
    97 	val Q = Free("Q",propT)
    97         val Q = Free("Q",propT)
    98 	val PQ = Logic.mk_implies(P,Q)
    98         val PQ = Logic.mk_implies(P,Q)
    99 	val PPQ = Logic.mk_implies(P,PQ)
    99         val PPQ = Logic.mk_implies(P,PQ)
   100 	val cP = cert P
   100         val cP = cert P
   101 	val cQ = cert Q
   101         val cQ = cert Q
   102 	val cPQ = cert PQ
   102         val cPQ = cert PQ
   103 	val cPPQ = cert PPQ
   103         val cPPQ = cert PPQ
   104 	val th1 = assume cPQ |> implies_intr_list [cPQ,cP]
   104         val th1 = assume cPQ |> implies_intr_list [cPQ,cP]
   105 	val th3 = assume cP
   105         val th3 = assume cP
   106 	val th4 = implies_elim_list (assume cPPQ) [th3,th3]
   106         val th4 = implies_elim_list (assume cPPQ) [th3,th3]
   107 				    |> implies_intr_list [cPPQ,cP]
   107                                     |> implies_intr_list [cPPQ,cP]
   108     in
   108     in
   109 	equal_intr th4 th1 |> standard
   109         equal_intr th4 th1 |> standard
   110     end
   110     end
   111 
   111 
   112 val imp_comm =
   112 val imp_comm =
   113     let
   113     let
   114 	val cert = cterm_of ProtoPure.thy
   114         val cert = cterm_of ProtoPure.thy
   115 	val P = Free("P",propT)
   115         val P = Free("P",propT)
   116 	val Q = Free("Q",propT)
   116         val Q = Free("Q",propT)
   117 	val R = Free("R",propT)
   117         val R = Free("R",propT)
   118 	val PQR = Logic.mk_implies(P,Logic.mk_implies(Q,R))
   118         val PQR = Logic.mk_implies(P,Logic.mk_implies(Q,R))
   119 	val QPR = Logic.mk_implies(Q,Logic.mk_implies(P,R))
   119         val QPR = Logic.mk_implies(Q,Logic.mk_implies(P,R))
   120 	val cP = cert P
   120         val cP = cert P
   121 	val cQ = cert Q
   121         val cQ = cert Q
   122 	val cPQR = cert PQR
   122         val cPQR = cert PQR
   123 	val cQPR = cert QPR
   123         val cQPR = cert QPR
   124 	val th1 = implies_elim_list (assume cPQR) [assume cP,assume cQ]
   124         val th1 = implies_elim_list (assume cPQR) [assume cP,assume cQ]
   125 				    |> implies_intr_list [cPQR,cQ,cP]
   125                                     |> implies_intr_list [cPQR,cQ,cP]
   126 	val th2 = implies_elim_list (assume cQPR) [assume cQ,assume cP]
   126         val th2 = implies_elim_list (assume cQPR) [assume cQ,assume cP]
   127 				    |> implies_intr_list [cQPR,cP,cQ]
   127                                     |> implies_intr_list [cQPR,cP,cQ]
   128     in
   128     in
   129 	equal_intr th1 th2 |> standard
   129         equal_intr th1 th2 |> standard
   130     end
   130     end
   131 
   131 
   132 val def_norm =
   132 val def_norm =
   133     let
   133     let
   134 	val cert = cterm_of ProtoPure.thy
   134         val cert = cterm_of ProtoPure.thy
   135 	val aT = TFree("'a",[])
   135         val aT = TFree("'a",[])
   136 	val bT = TFree("'b",[])
   136         val bT = TFree("'b",[])
   137 	val v = Free("v",aT)
   137         val v = Free("v",aT)
   138 	val P = Free("P",aT-->bT)
   138         val P = Free("P",aT-->bT)
   139 	val Q = Free("Q",aT-->bT)
   139         val Q = Free("Q",aT-->bT)
   140 	val cvPQ = cert (list_all ([("v",aT)],Logic.mk_equals(P $ Bound 0,Q $ Bound 0)))
   140         val cvPQ = cert (list_all ([("v",aT)],Logic.mk_equals(P $ Bound 0,Q $ Bound 0)))
   141 	val cPQ = cert (Logic.mk_equals(P,Q))
   141         val cPQ = cert (Logic.mk_equals(P,Q))
   142 	val cv = cert v
   142         val cv = cert v
   143 	val rew = assume cvPQ
   143         val rew = assume cvPQ
   144 			 |> forall_elim cv
   144                          |> forall_elim cv
   145 			 |> abstract_rule "v" cv
   145                          |> abstract_rule "v" cv
   146 	val (lhs,rhs) = Logic.dest_equals(concl_of rew)
   146         val (lhs,rhs) = Logic.dest_equals(concl_of rew)
   147 	val th1 = transitive (transitive
   147         val th1 = transitive (transitive
   148 				  (eta_conversion (cert lhs) |> symmetric)
   148                                   (eta_conversion (cert lhs) |> symmetric)
   149 				  rew)
   149                                   rew)
   150 			     (eta_conversion (cert rhs))
   150                              (eta_conversion (cert rhs))
   151 			     |> implies_intr cvPQ
   151                              |> implies_intr cvPQ
   152 	val th2 = combination (assume cPQ) (reflexive cv)
   152         val th2 = combination (assume cPQ) (reflexive cv)
   153 			      |> forall_intr cv
   153                               |> forall_intr cv
   154 			      |> implies_intr cPQ
   154                               |> implies_intr cPQ
   155     in
   155     in
   156 	equal_intr th1 th2 |> standard
   156         equal_intr th1 th2 |> standard
   157     end
   157     end
   158 
   158 
   159 val all_comm =
   159 val all_comm =
   160     let
   160     let
   161 	val cert = cterm_of ProtoPure.thy
   161         val cert = cterm_of ProtoPure.thy
   162 	val xT = TFree("'a",[])
   162         val xT = TFree("'a",[])
   163 	val yT = TFree("'b",[])
   163         val yT = TFree("'b",[])
   164 	val P = Free("P",xT-->yT-->propT)
   164         val P = Free("P",xT-->yT-->propT)
   165 	val lhs = all xT $ (Abs("x",xT,all yT $ (Abs("y",yT,P $ Bound 1 $ Bound 0))))
   165         val lhs = all xT $ (Abs("x",xT,all yT $ (Abs("y",yT,P $ Bound 1 $ Bound 0))))
   166 	val rhs = all yT $ (Abs("y",yT,all xT $ (Abs("x",xT,P $ Bound 0 $ Bound 1))))
   166         val rhs = all yT $ (Abs("y",yT,all xT $ (Abs("x",xT,P $ Bound 0 $ Bound 1))))
   167 	val cl = cert lhs
   167         val cl = cert lhs
   168 	val cr = cert rhs
   168         val cr = cert rhs
   169 	val cx = cert (Free("x",xT))
   169         val cx = cert (Free("x",xT))
   170 	val cy = cert (Free("y",yT))
   170         val cy = cert (Free("y",yT))
   171 	val th1 = assume cr
   171         val th1 = assume cr
   172 			 |> forall_elim_list [cy,cx]
   172                          |> forall_elim_list [cy,cx]
   173 			 |> forall_intr_list [cx,cy]
   173                          |> forall_intr_list [cx,cy]
   174 			 |> implies_intr cr
   174                          |> implies_intr cr
   175 	val th2 = assume cl
   175         val th2 = assume cl
   176 			 |> forall_elim_list [cx,cy]
   176                          |> forall_elim_list [cx,cy]
   177 			 |> forall_intr_list [cy,cx]
   177                          |> forall_intr_list [cy,cx]
   178 			 |> implies_intr cl
   178                          |> implies_intr cl
   179     in
   179     in
   180 	equal_intr th1 th2 |> standard
   180         equal_intr th1 th2 |> standard
   181     end
   181     end
   182 
   182 
   183 val equiv_comm =
   183 val equiv_comm =
   184     let
   184     let
   185 	val cert = cterm_of ProtoPure.thy
   185         val cert = cterm_of ProtoPure.thy
   186 	val T    = TFree("'a",[])
   186         val T    = TFree("'a",[])
   187 	val t    = Free("t",T)
   187         val t    = Free("t",T)
   188 	val u    = Free("u",T)
   188         val u    = Free("u",T)
   189 	val ctu  = cert (Logic.mk_equals(t,u))
   189         val ctu  = cert (Logic.mk_equals(t,u))
   190 	val cut  = cert (Logic.mk_equals(u,t))
   190         val cut  = cert (Logic.mk_equals(u,t))
   191 	val th1  = assume ctu |> symmetric |> implies_intr ctu
   191         val th1  = assume ctu |> symmetric |> implies_intr ctu
   192 	val th2  = assume cut |> symmetric |> implies_intr cut
   192         val th2  = assume cut |> symmetric |> implies_intr cut
   193     in
   193     in
   194 	equal_intr th1 th2 |> standard
   194         equal_intr th1 th2 |> standard
   195     end
   195     end
   196 
   196 
   197 (* This simplification procedure rewrites !!x y. P x y
   197 (* This simplification procedure rewrites !!x y. P x y
   198 deterministicly, in order for the normalization function, defined
   198 deterministicly, in order for the normalization function, defined
   199 below, to handle nested quantifiers robustly *)
   199 below, to handle nested quantifiers robustly *)
   201 local
   201 local
   202 
   202 
   203 exception RESULT of int
   203 exception RESULT of int
   204 
   204 
   205 fun find_bound n (Bound i) = if i = n then raise RESULT 0
   205 fun find_bound n (Bound i) = if i = n then raise RESULT 0
   206 			     else if i = n+1 then raise RESULT 1
   206                              else if i = n+1 then raise RESULT 1
   207 			     else ()
   207                              else ()
   208   | find_bound n (t $ u) = (find_bound n t; find_bound n u)
   208   | find_bound n (t $ u) = (find_bound n t; find_bound n u)
   209   | find_bound n (Abs(_,_,t)) = find_bound (n+1) t
   209   | find_bound n (Abs(_,_,t)) = find_bound (n+1) t
   210   | find_bound _ _ = ()
   210   | find_bound _ _ = ()
   211 
   211 
   212 fun swap_bound n (Bound i) = if i = n then Bound (n+1)
   212 fun swap_bound n (Bound i) = if i = n then Bound (n+1)
   213 			     else if i = n+1 then Bound n
   213                              else if i = n+1 then Bound n
   214 			     else Bound i
   214                              else Bound i
   215   | swap_bound n (t $ u) = (swap_bound n t $ swap_bound n u)
   215   | swap_bound n (t $ u) = (swap_bound n t $ swap_bound n u)
   216   | swap_bound n (Abs(x,xT,t)) = Abs(x,xT,swap_bound (n+1) t)
   216   | swap_bound n (Abs(x,xT,t)) = Abs(x,xT,swap_bound (n+1) t)
   217   | swap_bound n t = t
   217   | swap_bound n t = t
   218 
   218 
   219 fun rew_th thy (xv as (x,xT)) (yv as (y,yT)) t =
   219 fun rew_th thy (xv as (x,xT)) (yv as (y,yT)) t =
   220     let
   220     let
   221 	val lhs = list_all ([xv,yv],t)
   221         val lhs = list_all ([xv,yv],t)
   222 	val rhs = list_all ([yv,xv],swap_bound 0 t)
   222         val rhs = list_all ([yv,xv],swap_bound 0 t)
   223 	val rew = Logic.mk_equals (lhs,rhs)
   223         val rew = Logic.mk_equals (lhs,rhs)
   224 	val init = trivial (cterm_of thy rew)
   224         val init = trivial (cterm_of thy rew)
   225     in
   225     in
   226 	(all_comm RS init handle e => (message "rew_th"; OldGoals.print_exn e))
   226         (all_comm RS init handle e => (message "rew_th"; OldGoals.print_exn e))
   227     end
   227     end
   228 
   228 
   229 fun quant_rewrite thy assumes (t as Const("all",T1) $ (Abs(x,xT,Const("all",T2) $ Abs(y,yT,body)))) =
   229 fun quant_rewrite thy assumes (t as Const("all",T1) $ (Abs(x,xT,Const("all",T2) $ Abs(y,yT,body)))) =
   230     let
   230     let
   231 	val res = (find_bound 0 body;2) handle RESULT i => i
   231         val res = (find_bound 0 body;2) handle RESULT i => i
   232     in
   232     in
   233 	case res of
   233         case res of
   234 	    0 => SOME (rew_th thy (x,xT) (y,yT) body)
   234             0 => SOME (rew_th thy (x,xT) (y,yT) body)
   235 	  | 1 => if string_ord(y,x) = LESS
   235           | 1 => if string_ord(y,x) = LESS
   236 		 then
   236                  then
   237 		     let
   237                      let
   238 			 val newt = Const("all",T1) $ (Abs(y,xT,Const("all",T2) $ Abs(x,yT,body)))
   238                          val newt = Const("all",T1) $ (Abs(y,xT,Const("all",T2) $ Abs(x,yT,body)))
   239 			 val t_th    = reflexive (cterm_of thy t)
   239                          val t_th    = reflexive (cterm_of thy t)
   240 			 val newt_th = reflexive (cterm_of thy newt)
   240                          val newt_th = reflexive (cterm_of thy newt)
   241 		     in
   241                      in
   242 			 SOME (transitive t_th newt_th)
   242                          SOME (transitive t_th newt_th)
   243 		     end
   243                      end
   244 		 else NONE
   244                  else NONE
   245 	  | _ => error "norm_term (quant_rewrite) internal error"
   245           | _ => error "norm_term (quant_rewrite) internal error"
   246      end
   246      end
   247   | quant_rewrite _ _ _ = (warning "quant_rewrite: Unknown lhs"; NONE)
   247   | quant_rewrite _ _ _ = (warning "quant_rewrite: Unknown lhs"; NONE)
   248 
   248 
   249 fun freeze_thaw_term t =
   249 fun freeze_thaw_term t =
   250     let
   250     let
   251 	val tvars = term_tvars t
   251         val tvars = term_tvars t
   252 	val tfree_names = add_term_tfree_names(t,[])
   252         val tfree_names = add_term_tfree_names(t,[])
   253 	val (type_inst,_) =
   253         val (type_inst,_) =
   254 	    Library.foldl (fn ((inst,used),(w as (v,_),S)) =>
   254             Library.foldl (fn ((inst,used),(w as (v,_),S)) =>
   255 		      let
   255                       let
   256 			  val v' = Name.variant used v
   256                           val v' = Name.variant used v
   257 		      in
   257                       in
   258 			  ((w,TFree(v',S))::inst,v'::used)
   258                           ((w,TFree(v',S))::inst,v'::used)
   259 		      end)
   259                       end)
   260 		  (([],tfree_names),tvars)
   260                   (([],tfree_names),tvars)
   261 	val t' = subst_TVars type_inst t
   261         val t' = subst_TVars type_inst t
   262     in
   262     in
   263 	(t',map (fn (w,TFree(v,S)) => (v,TVar(w,S))
   263         (t',map (fn (w,TFree(v,S)) => (v,TVar(w,S))
   264 		  | _ => error "Internal error in Shuffler.freeze_thaw") type_inst)
   264                   | _ => error "Internal error in Shuffler.freeze_thaw") type_inst)
   265     end
   265     end
   266 
   266 
   267 fun inst_tfrees thy [] thm = thm
   267 fun inst_tfrees thy [] thm = thm
   268   | inst_tfrees thy ((name,U)::rest) thm = 
   268   | inst_tfrees thy ((name,U)::rest) thm =
   269     let
   269     let
   270 	val cU = ctyp_of thy U
   270         val cU = ctyp_of thy U
   271 	val tfrees = add_term_tfrees (prop_of thm,[])
   271         val tfrees = add_term_tfrees (prop_of thm,[])
   272 	val (rens, thm') = Thm.varifyT'
   272         val (rens, thm') = Thm.varifyT'
   273     (remove (op = o apsnd fst) name tfrees) thm
   273     (remove (op = o apsnd fst) name tfrees) thm
   274 	val mid = 
   274         val mid =
   275 	    case rens of
   275             case rens of
   276 		[] => thm'
   276                 [] => thm'
   277 	      | [((_, S), idx)] => instantiate
   277               | [((_, S), idx)] => instantiate
   278             ([(ctyp_of thy (TVar (idx, S)), cU)], []) thm'
   278             ([(ctyp_of thy (TVar (idx, S)), cU)], []) thm'
   279 	      | _ => error "Shuffler.inst_tfrees internal error"
   279               | _ => error "Shuffler.inst_tfrees internal error"
   280     in
   280     in
   281 	inst_tfrees thy rest mid
   281         inst_tfrees thy rest mid
   282     end
   282     end
   283 
   283 
   284 fun is_Abs (Abs _) = true
   284 fun is_Abs (Abs _) = true
   285   | is_Abs _ = false
   285   | is_Abs _ = false
   286 
   286 
   287 fun eta_redex (t $ Bound 0) =
   287 fun eta_redex (t $ Bound 0) =
   288     let
   288     let
   289 	fun free n (Bound i) = i = n
   289         fun free n (Bound i) = i = n
   290 	  | free n (t $ u) = free n t orelse free n u
   290           | free n (t $ u) = free n t orelse free n u
   291 	  | free n (Abs(_,_,t)) = free (n+1) t
   291           | free n (Abs(_,_,t)) = free (n+1) t
   292 	  | free n _ = false
   292           | free n _ = false
   293     in
   293     in
   294 	not (free 0 t)
   294         not (free 0 t)
   295     end
   295     end
   296   | eta_redex _ = false
   296   | eta_redex _ = false
   297 
   297 
   298 fun eta_contract thy assumes origt =
   298 fun eta_contract thy assumes origt =
   299     let
   299     let
   300 	val (typet,Tinst) = freeze_thaw_term origt
   300         val (typet,Tinst) = freeze_thaw_term origt
   301 	val (init,thaw) = freeze_thaw (reflexive (cterm_of thy typet))
   301         val (init,thaw) = freeze_thaw (reflexive (cterm_of thy typet))
   302 	val final = inst_tfrees thy Tinst o thaw
   302         val final = inst_tfrees thy Tinst o thaw
   303 	val t = #1 (Logic.dest_equals (prop_of init))
   303         val t = #1 (Logic.dest_equals (prop_of init))
   304 	val _ =
   304         val _ =
   305 	    let
   305             let
   306 		val lhs = #1 (Logic.dest_equals (prop_of (final init)))
   306                 val lhs = #1 (Logic.dest_equals (prop_of (final init)))
   307 	    in
   307             in
   308 		if not (lhs aconv origt)
   308                 if not (lhs aconv origt)
   309 		then (writeln "Something is utterly wrong: (orig,lhs,frozen type,t,tinst)";
   309                 then (writeln "Something is utterly wrong: (orig,lhs,frozen type,t,tinst)";
   310 		      writeln (string_of_cterm (cterm_of thy origt));
   310                       writeln (string_of_cterm (cterm_of thy origt));
   311 		      writeln (string_of_cterm (cterm_of thy lhs));
   311                       writeln (string_of_cterm (cterm_of thy lhs));
   312 		      writeln (string_of_cterm (cterm_of thy typet));
   312                       writeln (string_of_cterm (cterm_of thy typet));
   313 		      writeln (string_of_cterm (cterm_of thy t));
   313                       writeln (string_of_cterm (cterm_of thy t));
   314 		      app (fn (n,T) => writeln (n ^ ": " ^ (string_of_ctyp (ctyp_of thy T)))) Tinst;
   314                       app (fn (n,T) => writeln (n ^ ": " ^ (string_of_ctyp (ctyp_of thy T)))) Tinst;
   315 		      writeln "done")
   315                       writeln "done")
   316 		else ()
   316                 else ()
   317 	    end
   317             end
   318     in
   318     in
   319 	case t of
   319         case t of
   320 	    Const("all",_) $ (Abs(x,xT,Const("==",eqT) $ P $ Q)) =>
   320             Const("all",_) $ (Abs(x,xT,Const("==",eqT) $ P $ Q)) =>
   321 	    ((if eta_redex P andalso eta_redex Q
   321             ((if eta_redex P andalso eta_redex Q
   322 	      then
   322               then
   323 		  let
   323                   let
   324 		      val cert = cterm_of thy
   324                       val cert = cterm_of thy
   325 		      val v = Free(Name.variant (add_term_free_names(t,[])) "v",xT)
   325                       val v = Free(Name.variant (add_term_free_names(t,[])) "v",xT)
   326 		      val cv = cert v
   326                       val cv = cert v
   327 		      val ct = cert t
   327                       val ct = cert t
   328 		      val th = (assume ct)
   328                       val th = (assume ct)
   329 				   |> forall_elim cv
   329                                    |> forall_elim cv
   330 				   |> abstract_rule x cv
   330                                    |> abstract_rule x cv
   331 		      val ext_th = eta_conversion (cert (Abs(x,xT,P)))
   331                       val ext_th = eta_conversion (cert (Abs(x,xT,P)))
   332 		      val th' = transitive (symmetric ext_th) th
   332                       val th' = transitive (symmetric ext_th) th
   333 		      val cu = cert (prop_of th')
   333                       val cu = cert (prop_of th')
   334 		      val uth = combination (assume cu) (reflexive cv)
   334                       val uth = combination (assume cu) (reflexive cv)
   335 		      val uth' = (beta_conversion false (cert (Abs(x,xT,Q) $ v)))
   335                       val uth' = (beta_conversion false (cert (Abs(x,xT,Q) $ v)))
   336 				     |> transitive uth
   336                                      |> transitive uth
   337 				     |> forall_intr cv
   337                                      |> forall_intr cv
   338 				     |> implies_intr cu
   338                                      |> implies_intr cu
   339 		      val rew_th = equal_intr (th' |> implies_intr ct) uth'
   339                       val rew_th = equal_intr (th' |> implies_intr ct) uth'
   340 		      val res = final rew_th
   340                       val res = final rew_th
   341 		      val lhs = (#1 (Logic.dest_equals (prop_of res)))
   341                       val lhs = (#1 (Logic.dest_equals (prop_of res)))
   342 		  in
   342                   in
   343 		       SOME res
   343                        SOME res
   344 		  end
   344                   end
   345 	      else NONE)
   345               else NONE)
   346 	     handle e => OldGoals.print_exn e)
   346              handle e => OldGoals.print_exn e)
   347 	  | _ => NONE
   347           | _ => NONE
   348        end
   348        end
   349 
   349 
   350 fun beta_fun thy assume t =
   350 fun beta_fun thy assume t =
   351     SOME (beta_conversion true (cterm_of thy t))
   351     SOME (beta_conversion true (cterm_of thy t))
   352 
   352 
   353 val meta_sym_rew = thm "refl"
   353 val meta_sym_rew = thm "refl"
   354 
   354 
   355 fun equals_fun thy assume t =
   355 fun equals_fun thy assume t =
   356     case t of
   356     case t of
   357 	Const("op ==",_) $ u $ v => if Term.term_ord (u,v) = LESS then SOME (meta_sym_rew) else NONE
   357         Const("op ==",_) $ u $ v => if Term.term_ord (u,v) = LESS then SOME (meta_sym_rew) else NONE
   358       | _ => NONE
   358       | _ => NONE
   359 
   359 
   360 fun eta_expand thy assumes origt =
   360 fun eta_expand thy assumes origt =
   361     let
   361     let
   362 	val (typet,Tinst) = freeze_thaw_term origt
   362         val (typet,Tinst) = freeze_thaw_term origt
   363 	val (init,thaw) = freeze_thaw (reflexive (cterm_of thy typet))
   363         val (init,thaw) = freeze_thaw (reflexive (cterm_of thy typet))
   364 	val final = inst_tfrees thy Tinst o thaw
   364         val final = inst_tfrees thy Tinst o thaw
   365 	val t = #1 (Logic.dest_equals (prop_of init))
   365         val t = #1 (Logic.dest_equals (prop_of init))
   366 	val _ =
   366         val _ =
   367 	    let
   367             let
   368 		val lhs = #1 (Logic.dest_equals (prop_of (final init)))
   368                 val lhs = #1 (Logic.dest_equals (prop_of (final init)))
   369 	    in
   369             in
   370 		if not (lhs aconv origt)
   370                 if not (lhs aconv origt)
   371 		then (writeln "Something is utterly wrong: (orig,lhs,frozen type,t,tinst)";
   371                 then (writeln "Something is utterly wrong: (orig,lhs,frozen type,t,tinst)";
   372 		      writeln (string_of_cterm (cterm_of thy origt));
   372                       writeln (string_of_cterm (cterm_of thy origt));
   373 		      writeln (string_of_cterm (cterm_of thy lhs));
   373                       writeln (string_of_cterm (cterm_of thy lhs));
   374 		      writeln (string_of_cterm (cterm_of thy typet));
   374                       writeln (string_of_cterm (cterm_of thy typet));
   375 		      writeln (string_of_cterm (cterm_of thy t));
   375                       writeln (string_of_cterm (cterm_of thy t));
   376 		      app (fn (n,T) => writeln (n ^ ": " ^ (string_of_ctyp (ctyp_of thy T)))) Tinst;
   376                       app (fn (n,T) => writeln (n ^ ": " ^ (string_of_ctyp (ctyp_of thy T)))) Tinst;
   377 		      writeln "done")
   377                       writeln "done")
   378 		else ()
   378                 else ()
   379 	    end
   379             end
   380     in
   380     in
   381 	case t of
   381         case t of
   382 	    Const("==",T) $ P $ Q =>
   382             Const("==",T) $ P $ Q =>
   383 	    if is_Abs P orelse is_Abs Q
   383             if is_Abs P orelse is_Abs Q
   384 	    then (case domain_type T of
   384             then (case domain_type T of
   385 		      Type("fun",[aT,bT]) =>
   385                       Type("fun",[aT,bT]) =>
   386 		      let
   386                       let
   387 			  val cert = cterm_of thy
   387                           val cert = cterm_of thy
   388 			  val vname = Name.variant (add_term_free_names(t,[])) "v"
   388                           val vname = Name.variant (add_term_free_names(t,[])) "v"
   389 			  val v = Free(vname,aT)
   389                           val v = Free(vname,aT)
   390 			  val cv = cert v
   390                           val cv = cert v
   391 			  val ct = cert t
   391                           val ct = cert t
   392 			  val th1 = (combination (assume ct) (reflexive cv))
   392                           val th1 = (combination (assume ct) (reflexive cv))
   393 					|> forall_intr cv
   393                                         |> forall_intr cv
   394 					|> implies_intr ct
   394                                         |> implies_intr ct
   395 			  val concl = cert (concl_of th1)
   395                           val concl = cert (concl_of th1)
   396 			  val th2 = (assume concl)
   396                           val th2 = (assume concl)
   397 					|> forall_elim cv
   397                                         |> forall_elim cv
   398 					|> abstract_rule vname cv
   398                                         |> abstract_rule vname cv
   399 			  val (lhs,rhs) = Logic.dest_equals (prop_of th2)
   399                           val (lhs,rhs) = Logic.dest_equals (prop_of th2)
   400 			  val elhs = eta_conversion (cert lhs)
   400                           val elhs = eta_conversion (cert lhs)
   401 			  val erhs = eta_conversion (cert rhs)
   401                           val erhs = eta_conversion (cert rhs)
   402 			  val th2' = transitive
   402                           val th2' = transitive
   403 					 (transitive (symmetric elhs) th2)
   403                                          (transitive (symmetric elhs) th2)
   404 					 erhs
   404                                          erhs
   405 			  val res = equal_intr th1 (th2' |> implies_intr concl)
   405                           val res = equal_intr th1 (th2' |> implies_intr concl)
   406 			  val res' = final res
   406                           val res' = final res
   407 		      in
   407                       in
   408 			  SOME res'
   408                           SOME res'
   409 		      end
   409                       end
   410 		    | _ => NONE)
   410                     | _ => NONE)
   411 	    else NONE
   411             else NONE
   412 	  | _ => (error ("Bad eta_expand argument" ^ (string_of_cterm (cterm_of thy t))); NONE)
   412           | _ => (error ("Bad eta_expand argument" ^ (string_of_cterm (cterm_of thy t))); NONE)
   413     end
   413     end
   414     handle e => (writeln "eta_expand internal error"; OldGoals.print_exn e)
   414     handle e => (writeln "eta_expand internal error"; OldGoals.print_exn e)
   415 
   415 
   416 fun mk_tfree s = TFree("'"^s,[])
   416 fun mk_tfree s = TFree("'"^s,[])
   417 fun mk_free s t = Free (s,t)
   417 fun mk_free s t = Free (s,t)
   422 val R  = mk_free "R" (xT-->yT)
   422 val R  = mk_free "R" (xT-->yT)
   423 val S  = mk_free "S" xT
   423 val S  = mk_free "S" xT
   424 val S'  = mk_free "S'" xT
   424 val S'  = mk_free "S'" xT
   425 in
   425 in
   426 fun beta_simproc thy = Simplifier.simproc_i
   426 fun beta_simproc thy = Simplifier.simproc_i
   427 		      thy
   427                       thy
   428 		      "Beta-contraction"
   428                       "Beta-contraction"
   429 		      [Abs("x",xT,Q) $ S]
   429                       [Abs("x",xT,Q) $ S]
   430 		      beta_fun
   430                       beta_fun
   431 
   431 
   432 fun equals_simproc thy = Simplifier.simproc_i
   432 fun equals_simproc thy = Simplifier.simproc_i
   433 		      thy
   433                       thy
   434 		      "Ordered rewriting of meta equalities"
   434                       "Ordered rewriting of meta equalities"
   435 		      [Const("op ==",xT) $ S $ S']
   435                       [Const("op ==",xT) $ S $ S']
   436 		      equals_fun
   436                       equals_fun
   437 
   437 
   438 fun quant_simproc thy = Simplifier.simproc_i
   438 fun quant_simproc thy = Simplifier.simproc_i
   439 			   thy
   439                            thy
   440 			   "Ordered rewriting of nested quantifiers"
   440                            "Ordered rewriting of nested quantifiers"
   441 			   [all xT $ (Abs("x",xT,all yT $ (Abs("y",yT,P $ Bound 1 $ Bound 0))))]
   441                            [all xT $ (Abs("x",xT,all yT $ (Abs("y",yT,P $ Bound 1 $ Bound 0))))]
   442 			   quant_rewrite
   442                            quant_rewrite
   443 fun eta_expand_simproc thy = Simplifier.simproc_i
   443 fun eta_expand_simproc thy = Simplifier.simproc_i
   444 			 thy
   444                          thy
   445 			 "Smart eta-expansion by equivalences"
   445                          "Smart eta-expansion by equivalences"
   446 			 [Logic.mk_equals(Q,R)]
   446                          [Logic.mk_equals(Q,R)]
   447 			 eta_expand
   447                          eta_expand
   448 fun eta_contract_simproc thy = Simplifier.simproc_i
   448 fun eta_contract_simproc thy = Simplifier.simproc_i
   449 			 thy
   449                          thy
   450 			 "Smart handling of eta-contractions"
   450                          "Smart handling of eta-contractions"
   451 			 [all xT $ (Abs("x",xT,Logic.mk_equals(Q $ Bound 0,R $ Bound 0)))]
   451                          [all xT $ (Abs("x",xT,Logic.mk_equals(Q $ Bound 0,R $ Bound 0)))]
   452 			 eta_contract
   452                          eta_contract
   453 end
   453 end
   454 
   454 
   455 (* Disambiguates the names of bound variables in a term, returning t
   455 (* Disambiguates the names of bound variables in a term, returning t
   456 == t' where all the names of bound variables in t' are unique *)
   456 == t' where all the names of bound variables in t' are unique *)
   457 
   457 
   458 fun disamb_bound thy t =
   458 fun disamb_bound thy t =
   459     let
   459     let
   460 	
   460 
   461 	fun F (t $ u,idx) =
   461         fun F (t $ u,idx) =
   462 	    let
   462             let
   463 		val (t',idx') = F (t,idx)
   463                 val (t',idx') = F (t,idx)
   464 		val (u',idx'') = F (u,idx')
   464                 val (u',idx'') = F (u,idx')
   465 	    in
   465             in
   466 		(t' $ u',idx'')
   466                 (t' $ u',idx'')
   467 	    end
   467             end
   468 	  | F (Abs(x,xT,t),idx) =
   468           | F (Abs(x,xT,t),idx) =
   469 	    let
   469             let
   470 		val x' = "x" ^ (LargeInt.toString idx) (* amazing *)
   470                 val x' = "x" ^ (LargeInt.toString idx) (* amazing *)
   471 		val (t',idx') = F (t,idx+1)
   471                 val (t',idx') = F (t,idx+1)
   472 	    in
   472             in
   473 		(Abs(x',xT,t'),idx')
   473                 (Abs(x',xT,t'),idx')
   474 	    end
   474             end
   475 	  | F arg = arg
   475           | F arg = arg
   476 	val (t',_) = F (t,0)
   476         val (t',_) = F (t,0)
   477 	val ct = cterm_of thy t
   477         val ct = cterm_of thy t
   478 	val ct' = cterm_of thy t'
   478         val ct' = cterm_of thy t'
   479 	val res = transitive (reflexive ct) (reflexive ct')
   479         val res = transitive (reflexive ct) (reflexive ct')
   480 	val _ = message ("disamb_term: " ^ (string_of_thm res))
   480         val _ = message ("disamb_term: " ^ (string_of_thm res))
   481     in
   481     in
   482 	res
   482         res
   483     end
   483     end
   484 
   484 
   485 (* Transforms a term t to some normal form t', returning the theorem t
   485 (* Transforms a term t to some normal form t', returning the theorem t
   486 == t'.  This is originally a help function for make_equal, but might
   486 == t'.  This is originally a help function for make_equal, but might
   487 be handy in its own right, for example for indexing terms. *)
   487 be handy in its own right, for example for indexing terms. *)
   488 
   488 
   489 fun norm_term thy t =
   489 fun norm_term thy t =
   490     let
   490     let
   491 	val norms = ShuffleData.get thy
   491         val norms = ShuffleData.get thy
   492 	val ss = Simplifier.theory_context thy empty_ss
   492         val ss = Simplifier.theory_context thy empty_ss
   493           setmksimps single
   493           setmksimps single
   494 	  addsimps (map (Thm.transfer thy) norms)
   494           addsimps (map (Thm.transfer thy) norms)
   495           addsimprocs [quant_simproc thy, eta_expand_simproc thy,eta_contract_simproc thy]
   495           addsimprocs [quant_simproc thy, eta_expand_simproc thy,eta_contract_simproc thy]
   496 	fun chain f th =
   496         fun chain f th =
   497 	    let
   497             let
   498                 val rhs = snd (dest_equals (cprop_of th))
   498                 val rhs = snd (dest_equals (cprop_of th))
   499       	    in
   499             in
   500 		transitive th (f rhs)
   500                 transitive th (f rhs)
   501 	    end
   501             end
   502 	val th =
   502         val th =
   503             t |> disamb_bound thy
   503             t |> disamb_bound thy
   504 	      |> chain (Simplifier.full_rewrite ss)
   504               |> chain (Simplifier.full_rewrite ss)
   505               |> chain eta_conversion
   505               |> chain eta_conversion
   506 	      |> strip_shyps
   506               |> strip_shyps
   507 	val _ = message ("norm_term: " ^ (string_of_thm th))
   507         val _ = message ("norm_term: " ^ (string_of_thm th))
   508     in
   508     in
   509 	th
   509         th
   510     end
   510     end
   511     handle e => (writeln "norm_term internal error"; print_sign_exn thy e)
   511     handle e => (writeln "norm_term internal error"; print_sign_exn thy e)
   512 
   512 
   513 
   513 
   514 (* Closes a theorem with respect to free and schematic variables (does
   514 (* Closes a theorem with respect to free and schematic variables (does
   515 not touch type variables, though). *)
   515 not touch type variables, though). *)
   516 
   516 
   517 fun close_thm th =
   517 fun close_thm th =
   518     let
   518     let
   519 	val thy = sign_of_thm th
   519         val thy = sign_of_thm th
   520 	val c = prop_of th
   520         val c = prop_of th
   521 	val vars = add_term_frees (c,add_term_vars(c,[]))
   521         val vars = add_term_frees (c,add_term_vars(c,[]))
   522     in
   522     in
   523 	Drule.forall_intr_list (map (cterm_of thy) vars) th
   523         Drule.forall_intr_list (map (cterm_of thy) vars) th
   524     end
   524     end
   525     handle e => (writeln "close_thm internal error"; OldGoals.print_exn e)
   525     handle e => (writeln "close_thm internal error"; OldGoals.print_exn e)
   526 
   526 
   527 (* Normalizes a theorem's conclusion using norm_term. *)
   527 (* Normalizes a theorem's conclusion using norm_term. *)
   528 
   528 
   529 fun norm_thm thy th =
   529 fun norm_thm thy th =
   530     let
   530     let
   531 	val c = prop_of th
   531         val c = prop_of th
   532     in
   532     in
   533 	equal_elim (norm_term thy c) th
   533         equal_elim (norm_term thy c) th
   534     end
   534     end
   535 
   535 
   536 (* make_equal thy t u tries to construct the theorem t == u under the
   536 (* make_equal thy t u tries to construct the theorem t == u under the
   537 signature thy.  If it succeeds, SOME (t == u) is returned, otherwise
   537 signature thy.  If it succeeds, SOME (t == u) is returned, otherwise
   538 NONE is returned. *)
   538 NONE is returned. *)
   539 
   539 
   540 fun make_equal thy t u =
   540 fun make_equal thy t u =
   541     let
   541     let
   542 	val t_is_t' = norm_term thy t
   542         val t_is_t' = norm_term thy t
   543 	val u_is_u' = norm_term thy u
   543         val u_is_u' = norm_term thy u
   544 	val th = transitive t_is_t' (symmetric u_is_u')
   544         val th = transitive t_is_t' (symmetric u_is_u')
   545 	val _ = message ("make_equal: SOME " ^ (string_of_thm th))
   545         val _ = message ("make_equal: SOME " ^ (string_of_thm th))
   546     in
   546     in
   547 	SOME th
   547         SOME th
   548     end
   548     end
   549     handle e as THM _ => (message "make_equal: NONE";NONE)
   549     handle e as THM _ => (message "make_equal: NONE";NONE)
   550 			 
   550 
   551 fun match_consts ignore t (* th *) =
   551 fun match_consts ignore t (* th *) =
   552     let
   552     let
   553 	fun add_consts (Const (c, _), cs) =
   553         fun add_consts (Const (c, _), cs) =
   554 	    if c mem_string ignore
   554             if c mem_string ignore
   555 	    then cs
   555             then cs
   556 	    else insert (op =) c cs
   556             else insert (op =) c cs
   557 	  | add_consts (t $ u, cs) = add_consts (t, add_consts (u, cs))
   557           | add_consts (t $ u, cs) = add_consts (t, add_consts (u, cs))
   558 	  | add_consts (Abs (_, _, t), cs) = add_consts (t, cs)
   558           | add_consts (Abs (_, _, t), cs) = add_consts (t, cs)
   559 	  | add_consts (_, cs) = cs
   559           | add_consts (_, cs) = cs
   560 	val t_consts = add_consts(t,[])
   560         val t_consts = add_consts(t,[])
   561     in
   561     in
   562      fn (name,th) =>
   562      fn (name,th) =>
   563 	let
   563         let
   564 	    val th_consts = add_consts(prop_of th,[])
   564             val th_consts = add_consts(prop_of th,[])
   565 	in
   565         in
   566 	    eq_set(t_consts,th_consts)
   566             eq_set(t_consts,th_consts)
   567 	end
   567         end
   568     end
   568     end
   569     
   569 
   570 val collect_ignored =
   570 val collect_ignored =
   571     fold_rev (fn thm => fn cs =>
   571     fold_rev (fn thm => fn cs =>
   572 	      let
   572               let
   573 		  val (lhs,rhs) = Logic.dest_equals (prop_of thm)
   573                   val (lhs,rhs) = Logic.dest_equals (prop_of thm)
   574 		  val ignore_lhs = term_consts lhs \\ term_consts rhs
   574                   val ignore_lhs = term_consts lhs \\ term_consts rhs
   575 		  val ignore_rhs = term_consts rhs \\ term_consts lhs
   575                   val ignore_rhs = term_consts rhs \\ term_consts lhs
   576 	      in
   576               in
   577 		  fold_rev (insert (op =)) cs (ignore_lhs @ ignore_rhs)
   577                   fold_rev (insert (op =)) cs (ignore_lhs @ ignore_rhs)
   578 	      end)
   578               end)
   579 
   579 
   580 (* set_prop t thms tries to make a theorem with the proposition t from
   580 (* set_prop t thms tries to make a theorem with the proposition t from
   581 one of the theorems thms, by shuffling the propositions around.  If it
   581 one of the theorems thms, by shuffling the propositions around.  If it
   582 succeeds, SOME theorem is returned, otherwise NONE.  *)
   582 succeeds, SOME theorem is returned, otherwise NONE.  *)
   583 
   583 
   584 fun set_prop thy t =
   584 fun set_prop thy t =
   585     let
   585     let
   586 	val vars = add_term_frees (t,add_term_vars (t,[]))
   586         val vars = add_term_frees (t,add_term_vars (t,[]))
   587 	val closed_t = Library.foldr (fn (v, body) =>
   587         val closed_t = Library.foldr (fn (v, body) =>
   588       let val vT = type_of v in all vT $ (Abs ("x", vT, abstract_over (v, body))) end) (vars, t)
   588       let val vT = type_of v in all vT $ (Abs ("x", vT, abstract_over (v, body))) end) (vars, t)
   589 	val rew_th = norm_term thy closed_t
   589         val rew_th = norm_term thy closed_t
   590 	val rhs = snd (dest_equals (cprop_of rew_th))
   590         val rhs = snd (dest_equals (cprop_of rew_th))
   591 
   591 
   592 	val shuffles = ShuffleData.get thy
   592         val shuffles = ShuffleData.get thy
   593 	fun process [] = NONE
   593         fun process [] = NONE
   594 	  | process ((name,th)::thms) =
   594           | process ((name,th)::thms) =
   595 	    let
   595             let
   596 		val norm_th = Thm.varifyT (norm_thm thy (close_thm (Thm.transfer thy th)))
   596                 val norm_th = Thm.varifyT (norm_thm thy (close_thm (Thm.transfer thy th)))
   597 		val triv_th = trivial rhs
   597                 val triv_th = trivial rhs
   598 		val _ = message ("Shuffler.set_prop: Gluing together " ^ (string_of_thm norm_th) ^ " and " ^ (string_of_thm triv_th))
   598                 val _ = message ("Shuffler.set_prop: Gluing together " ^ (string_of_thm norm_th) ^ " and " ^ (string_of_thm triv_th))
   599 		val mod_th = case Seq.pull (bicompose false (*true*) (false,norm_th,0) 1 triv_th) of
   599                 val mod_th = case Seq.pull (bicompose false (*true*) (false,norm_th,0) 1 triv_th) of
   600 				 SOME(th,_) => SOME th
   600                                  SOME(th,_) => SOME th
   601 			       | NONE => NONE
   601                                | NONE => NONE
   602 	    in
   602             in
   603 		case mod_th of
   603                 case mod_th of
   604 		    SOME mod_th =>
   604                     SOME mod_th =>
   605 		    let
   605                     let
   606 			val closed_th = equal_elim (symmetric rew_th) mod_th
   606                         val closed_th = equal_elim (symmetric rew_th) mod_th
   607 		    in
   607                     in
   608 			message ("Shuffler.set_prop succeeded by " ^ name);
   608                         message ("Shuffler.set_prop succeeded by " ^ name);
   609 			SOME (name,forall_elim_list (map (cterm_of thy) vars) closed_th)
   609                         SOME (name,forall_elim_list (map (cterm_of thy) vars) closed_th)
   610 		    end
   610                     end
   611 		  | NONE => process thms
   611                   | NONE => process thms
   612 	    end
   612             end
   613 	    handle e as THM _ => process thms
   613             handle e as THM _ => process thms
   614     in
   614     in
   615 	fn thms =>
   615         fn thms =>
   616 	   case process thms of
   616            case process thms of
   617 	       res as SOME (name,th) => if (prop_of th) aconv t
   617                res as SOME (name,th) => if (prop_of th) aconv t
   618 					then res
   618                                         then res
   619 					else error "Internal error in set_prop"
   619                                         else error "Internal error in set_prop"
   620 	     | NONE => NONE
   620              | NONE => NONE
   621     end
   621     end
   622     handle e => (writeln "set_prop internal error"; OldGoals.print_exn e)
   622     handle e => (writeln "set_prop internal error"; OldGoals.print_exn e)
   623 
   623 
   624 fun find_potential thy t =
   624 fun find_potential thy t =
   625     let
   625     let
   626 	val shuffles = ShuffleData.get thy
   626         val shuffles = ShuffleData.get thy
   627 	val ignored = collect_ignored shuffles []
   627         val ignored = collect_ignored shuffles []
   628 	val rel_consts = term_consts t \\ ignored
   628         val rel_consts = term_consts t \\ ignored
   629 	val pot_thms = PureThy.thms_containing_consts thy rel_consts
   629         val pot_thms = PureThy.thms_containing_consts thy rel_consts
   630     in
   630     in
   631 	List.filter (match_consts ignored t) pot_thms
   631         List.filter (match_consts ignored t) pot_thms
   632     end
   632     end
   633 
   633 
   634 fun gen_shuffle_tac thy search thms i st =
   634 fun gen_shuffle_tac thy search thms i st =
   635     let
   635     let
   636 	val _ = message ("Shuffling " ^ (string_of_thm st))
   636         val _ = message ("Shuffling " ^ (string_of_thm st))
   637 	val t = List.nth(prems_of st,i-1)
   637         val t = List.nth(prems_of st,i-1)
   638 	val set = set_prop thy t
   638         val set = set_prop thy t
   639 	fun process_tac thms st =
   639         fun process_tac thms st =
   640 	    case set thms of
   640             case set thms of
   641 		SOME (_,th) => Seq.of_list (compose (th,i,st))
   641                 SOME (_,th) => Seq.of_list (compose (th,i,st))
   642 	      | NONE => Seq.empty
   642               | NONE => Seq.empty
   643     in
   643     in
   644 	(process_tac thms APPEND (if search
   644         (process_tac thms APPEND (if search
   645 				  then process_tac (find_potential thy t)
   645                                   then process_tac (find_potential thy t)
   646 				  else no_tac)) st
   646                                   else no_tac)) st
   647     end
   647     end
   648 
   648 
   649 fun shuffle_tac thms i st =
   649 fun shuffle_tac thms i st =
   650     gen_shuffle_tac (the_context()) false thms i st
   650     gen_shuffle_tac (the_context()) false thms i st
   651 
   651 
   652 fun search_tac thms i st =
   652 fun search_tac thms i st =
   653     gen_shuffle_tac (the_context()) true thms i st
   653     gen_shuffle_tac (the_context()) true thms i st
   654 
   654 
   655 fun shuffle_meth (thms:thm list) ctxt =
   655 fun shuffle_meth (thms:thm list) ctxt =
   656     let
   656     let
   657 	val thy = ProofContext.theory_of ctxt
   657         val thy = ProofContext.theory_of ctxt
   658     in
   658     in
   659 	Method.SIMPLE_METHOD' HEADGOAL (gen_shuffle_tac thy false (map (pair "") thms))
   659         Method.SIMPLE_METHOD' (gen_shuffle_tac thy false (map (pair "") thms))
   660     end
   660     end
   661 
   661 
   662 fun search_meth ctxt =
   662 fun search_meth ctxt =
   663     let
   663     let
   664 	val thy = ProofContext.theory_of ctxt
   664         val thy = ProofContext.theory_of ctxt
   665 	val prems = Assumption.prems_of ctxt
   665         val prems = Assumption.prems_of ctxt
   666     in
   666     in
   667 	Method.SIMPLE_METHOD' HEADGOAL (gen_shuffle_tac thy true (map (pair "premise") prems))
   667         Method.SIMPLE_METHOD' (gen_shuffle_tac thy true (map (pair "premise") prems))
   668     end
   668     end
   669 
   669 
   670 val print_shuffles = ShuffleData.print
   670 val print_shuffles = ShuffleData.print
   671 
   671 
   672 fun add_shuffle_rule thm thy =
   672 fun add_shuffle_rule thm thy =
   673     let
   673     let
   674 	val shuffles = ShuffleData.get thy
   674         val shuffles = ShuffleData.get thy
   675     in
   675     in
   676 	if exists (curry Thm.eq_thm thm) shuffles
   676         if exists (curry Thm.eq_thm thm) shuffles
   677 	then (warning ((string_of_thm thm) ^ " already known to the shuffler");
   677         then (warning ((string_of_thm thm) ^ " already known to the shuffler");
   678 	      thy)
   678               thy)
   679 	else ShuffleData.put (thm::shuffles) thy
   679         else ShuffleData.put (thm::shuffles) thy
   680     end
   680     end
   681 
   681 
   682 val shuffle_attr = Thm.declaration_attribute (fn th => Context.mapping (add_shuffle_rule th) I);
   682 val shuffle_attr = Thm.declaration_attribute (fn th => Context.mapping (add_shuffle_rule th) I);
   683 
   683 
   684 val setup =
   684 val setup =