70 string * Term.typ -> int -> Thm.thm -> Thm.thm Seq.seq |
70 string * Term.typ -> int -> Thm.thm -> Thm.thm Seq.seq |
71 val casesplit_name : string -> int -> Thm.thm -> Thm.thm Seq.seq |
71 val casesplit_name : string -> int -> Thm.thm -> Thm.thm Seq.seq |
72 |
72 |
73 (* finding a free var to split *) |
73 (* finding a free var to split *) |
74 val find_term_split : |
74 val find_term_split : |
75 Term.term * Term.term -> (string * Term.typ) Library.option |
75 Term.term * Term.term -> (string * Term.typ) option |
76 val find_thm_split : |
76 val find_thm_split : |
77 Thm.thm -> int -> Thm.thm -> (string * Term.typ) Library.option |
77 Thm.thm -> int -> Thm.thm -> (string * Term.typ) option |
78 val find_thms_split : |
78 val find_thms_split : |
79 Thm.thm list -> int -> Thm.thm -> (string * Term.typ) Library.option |
79 Thm.thm list -> int -> Thm.thm -> (string * Term.typ) option |
80 |
80 |
81 (* try to recursively split conjectured thm to given list of thms *) |
81 (* try to recursively split conjectured thm to given list of thms *) |
82 val splitto : Thm.thm list -> Thm.thm -> Thm.thm |
82 val splitto : Thm.thm list -> Thm.thm -> Thm.thm |
83 |
83 |
84 (* for use with the recdef package *) |
84 (* for use with the recdef package *) |
127 | TFree(s,_) => raise ERROR_MESSAGE |
127 | TFree(s,_) => raise ERROR_MESSAGE |
128 ("Free type: " ^ s) |
128 ("Free type: " ^ s) |
129 | TVar((s,i),_) => raise ERROR_MESSAGE |
129 | TVar((s,i),_) => raise ERROR_MESSAGE |
130 ("Free variable: " ^ s) |
130 ("Free variable: " ^ s) |
131 val dt = case (Symtab.lookup (dtypestab,ty_str)) |
131 val dt = case (Symtab.lookup (dtypestab,ty_str)) |
132 of Some dt => dt |
132 of SOME dt => dt |
133 | None => raise ERROR_MESSAGE ("Not a Datatype: " ^ ty_str) |
133 | NONE => raise ERROR_MESSAGE ("Not a Datatype: " ^ ty_str) |
134 in |
134 in |
135 cases_thm_of_induct_thm (#induction dt) |
135 cases_thm_of_induct_thm (#induction dt) |
136 end; |
136 end; |
137 |
137 |
138 (* |
138 (* |
204 |
204 |
205 val freets = Term.term_frees gt; |
205 val freets = Term.term_frees gt; |
206 fun getter x = |
206 fun getter x = |
207 let val (n,ty) = Term.dest_Free x in |
207 let val (n,ty) = Term.dest_Free x in |
208 (if vstr = n orelse vstr = Syntax.dest_skolem n |
208 (if vstr = n orelse vstr = Syntax.dest_skolem n |
209 then Some (n,ty) else None ) |
209 then SOME (n,ty) else NONE ) |
210 handle LIST _ => None |
210 handle LIST _ => NONE |
211 end; |
211 end; |
212 val (n,ty) = case Library.get_first getter freets |
212 val (n,ty) = case Library.get_first getter freets |
213 of Some (n, ty) => (n, ty) |
213 of SOME (n, ty) => (n, ty) |
214 | _ => raise ERROR_MESSAGE ("no such variable " ^ vstr); |
214 | _ => raise ERROR_MESSAGE ("no such variable " ^ vstr); |
215 val sgn = Thm.sign_of_thm th; |
215 val sgn = Thm.sign_of_thm th; |
216 |
216 |
217 val splitter_thm = mk_casesplit_goal_thm sgn (n,ty) gt; |
217 val splitter_thm = mk_casesplit_goal_thm sgn (n,ty) gt; |
218 val nsplits = Thm.nprems_of splitter_thm; |
218 val nsplits = Thm.nprems_of splitter_thm; |
245 |
245 |
246 (* assuming two twems are identical except for a free in one at a |
246 (* assuming two twems are identical except for a free in one at a |
247 subterm, or constant in another, ie assume that one term is a plit of |
247 subterm, or constant in another, ie assume that one term is a plit of |
248 another, then gives back the free variable that has been split. *) |
248 another, then gives back the free variable that has been split. *) |
249 exception find_split_exp of string |
249 exception find_split_exp of string |
250 fun find_term_split (Free v, _ $ _) = Some v |
250 fun find_term_split (Free v, _ $ _) = SOME v |
251 | find_term_split (Free v, Const _) = Some v |
251 | find_term_split (Free v, Const _) = SOME v |
252 | find_term_split (Free v, Abs _) = Some v (* do we really want this case? *) |
252 | find_term_split (Free v, Abs _) = SOME v (* do we really want this case? *) |
253 | find_term_split (Free v, Var _) = None (* keep searching *) |
253 | find_term_split (Free v, Var _) = NONE (* keep searching *) |
254 | find_term_split (a $ b, a2 $ b2) = |
254 | find_term_split (a $ b, a2 $ b2) = |
255 (case find_term_split (a, a2) of |
255 (case find_term_split (a, a2) of |
256 None => find_term_split (b,b2) |
256 NONE => find_term_split (b,b2) |
257 | vopt => vopt) |
257 | vopt => vopt) |
258 | find_term_split (Abs(_,ty,t1), Abs(_,ty2,t2)) = |
258 | find_term_split (Abs(_,ty,t1), Abs(_,ty2,t2)) = |
259 find_term_split (t1, t2) |
259 find_term_split (t1, t2) |
260 | find_term_split (Const (x,ty), Const(x2,ty2)) = |
260 | find_term_split (Const (x,ty), Const(x2,ty2)) = |
261 if x = x2 then None else (* keep searching *) |
261 if x = x2 then NONE else (* keep searching *) |
262 raise find_split_exp (* stop now *) |
262 raise find_split_exp (* stop now *) |
263 "Terms are not identical upto a free varaible! (Consts)" |
263 "Terms are not identical upto a free varaible! (Consts)" |
264 | find_term_split (Bound i, Bound j) = |
264 | find_term_split (Bound i, Bound j) = |
265 if i = j then None else (* keep searching *) |
265 if i = j then NONE else (* keep searching *) |
266 raise find_split_exp (* stop now *) |
266 raise find_split_exp (* stop now *) |
267 "Terms are not identical upto a free varaible! (Bound)" |
267 "Terms are not identical upto a free varaible! (Bound)" |
268 | find_term_split (a, b) = |
268 | find_term_split (a, b) = |
269 raise find_split_exp (* stop now *) |
269 raise find_split_exp (* stop now *) |
270 "Terms are not identical upto a free varaible! (Other)"; |
270 "Terms are not identical upto a free varaible! (Other)"; |
272 (* assume that "splitth" is a case split form of subgoal i of "genth", |
272 (* assume that "splitth" is a case split form of subgoal i of "genth", |
273 then look for a free variable to split, breaking the subgoal closer to |
273 then look for a free variable to split, breaking the subgoal closer to |
274 splitth. *) |
274 splitth. *) |
275 fun find_thm_split splitth i genth = |
275 fun find_thm_split splitth i genth = |
276 find_term_split (Logic.get_goal (Thm.prop_of genth) i, |
276 find_term_split (Logic.get_goal (Thm.prop_of genth) i, |
277 Thm.concl_of splitth) handle find_split_exp _ => None; |
277 Thm.concl_of splitth) handle find_split_exp _ => NONE; |
278 |
278 |
279 (* as above but searches "splitths" for a theorem that suggest a case split *) |
279 (* as above but searches "splitths" for a theorem that suggest a case split *) |
280 fun find_thms_split splitths i genth = |
280 fun find_thms_split splitths i genth = |
281 Library.get_first (fn sth => find_thm_split sth i genth) splitths; |
281 Library.get_first (fn sth => find_thm_split sth i genth) splitths; |
282 |
282 |
302 fun solve_by_splitth th split = |
302 fun solve_by_splitth th split = |
303 Thm.biresolution false [(false,split)] 1 th; |
303 Thm.biresolution false [(false,split)] 1 th; |
304 |
304 |
305 fun split th = |
305 fun split th = |
306 (case find_thms_split splitths 1 th of |
306 (case find_thms_split splitths 1 th of |
307 None => |
307 NONE => |
308 (writeln "th:"; |
308 (writeln "th:"; |
309 Display.print_thm th; writeln "split ths:"; |
309 Display.print_thm th; writeln "split ths:"; |
310 Display.print_thms splitths; writeln "\n--"; |
310 Display.print_thms splitths; writeln "\n--"; |
311 raise ERROR_MESSAGE "splitto: cannot find variable to split on") |
311 raise ERROR_MESSAGE "splitto: cannot find variable to split on") |
312 | Some v => |
312 | SOME v => |
313 let |
313 let |
314 val gt = Data.dest_Trueprop (nth_elem(0, Thm.prems_of th)); |
314 val gt = Data.dest_Trueprop (nth_elem(0, Thm.prems_of th)); |
315 val split_thm = mk_casesplit_goal_thm sgn v gt; |
315 val split_thm = mk_casesplit_goal_thm sgn v gt; |
316 val (subthms, expf) = IsaND.fixed_subgoal_thms split_thm; |
316 val (subthms, expf) = IsaND.fixed_subgoal_thms split_thm; |
317 in |
317 in |
338 |
338 |
339 (* derive eqs, assuming strict, ie the rules have no assumptions = all |
339 (* derive eqs, assuming strict, ie the rules have no assumptions = all |
340 the well-foundness conditions have been solved. *) |
340 the well-foundness conditions have been solved. *) |
341 local |
341 local |
342 fun get_related_thms i = |
342 fun get_related_thms i = |
343 mapfilter ((fn (r,x) => if x = i then Some r else None)); |
343 mapfilter ((fn (r,x) => if x = i then SOME r else NONE)); |
344 |
344 |
345 fun solve_eq (th, [], i) = |
345 fun solve_eq (th, [], i) = |
346 raise ERROR_MESSAGE "derive_init_eqs: missing rules" |
346 raise ERROR_MESSAGE "derive_init_eqs: missing rules" |
347 | solve_eq (th, [a], i) = (a, i) |
347 | solve_eq (th, [a], i) = (a, i) |
348 | solve_eq (th, splitths as (_ :: _), i) = (splitto splitths th,i); |
348 | solve_eq (th, splitths as (_ :: _), i) = (splitto splitths th,i); |