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 = |