10 |
10 |
11 infix 4 addsplits delsplits; |
11 infix 4 addsplits delsplits; |
12 |
12 |
13 signature SPLITTER_DATA = |
13 signature SPLITTER_DATA = |
14 sig |
14 sig |
15 structure Simplifier: SIMPLIFIER |
|
16 val mk_eq : thm -> thm |
15 val mk_eq : thm -> thm |
17 val meta_eq_to_iff: thm (* "x == y ==> x = y" *) |
16 val meta_eq_to_iff: thm (* "x == y ==> x = y" *) |
18 val iffD : thm (* "[| P = Q; Q |] ==> P" *) |
17 val iffD : thm (* "[| P = Q; Q |] ==> P" *) |
19 val disjE : thm (* "[| P | Q; P ==> R; Q ==> R |] ==> R" *) |
18 val disjE : thm (* "[| P | Q; P ==> R; Q ==> R |] ==> R" *) |
20 val conjE : thm (* "[| P & Q; [| P; Q |] ==> R |] ==> R" *) |
19 val conjE : thm (* "[| P & Q; [| P; Q |] ==> R |] ==> R" *) |
41 val split_modifiers : (Args.T list -> (Method.modifier * Args.T list)) list |
39 val split_modifiers : (Args.T list -> (Method.modifier * Args.T list)) list |
42 val setup: (theory -> theory) list |
40 val setup: (theory -> theory) list |
43 end; |
41 end; |
44 |
42 |
45 functor SplitterFun(Data: SPLITTER_DATA): SPLITTER = |
43 functor SplitterFun(Data: SPLITTER_DATA): SPLITTER = |
46 struct |
44 struct |
47 |
|
48 structure Simplifier = Data.Simplifier; |
|
49 type simpset = Simplifier.simpset; |
|
50 |
45 |
51 val Const ("==>", _) $ (Const ("Trueprop", _) $ |
46 val Const ("==>", _) $ (Const ("Trueprop", _) $ |
52 (Const (const_not, _) $ _ )) $ _ = #prop (rep_thm(Data.notnotD)); |
47 (Const (const_not, _) $ _ )) $ _ = #prop (rep_thm(Data.notnotD)); |
53 |
48 |
54 val Const ("==>", _) $ (Const ("Trueprop", _) $ |
49 val Const ("==>", _) $ (Const ("Trueprop", _) $ |
84 |
79 |
85 val trlift = lift RS transitive_thm; |
80 val trlift = lift RS transitive_thm; |
86 val _ $ (P $ _) $ _ = concl_of trlift; |
81 val _ $ (P $ _) $ _ = concl_of trlift; |
87 |
82 |
88 |
83 |
89 (************************************************************************ |
84 (************************************************************************ |
90 Set up term for instantiation of P in the lift-theorem |
85 Set up term for instantiation of P in the lift-theorem |
91 |
86 |
92 Ts : types of parameters (i.e. variables bound by meta-quantifiers) |
87 Ts : types of parameters (i.e. variables bound by meta-quantifiers) |
93 t : lefthand side of meta-equality in subgoal |
88 t : lefthand side of meta-equality in subgoal |
94 the lift theorem is applied to (see select) |
89 the lift theorem is applied to (see select) |
95 pos : "path" leading to abstraction, coded as a list |
90 pos : "path" leading to abstraction, coded as a list |
96 T : type of body of P(...) |
91 T : type of body of P(...) |
107 val v2 = ListPair.map var (us, (i+p) upto (i+length(ts)-2)) |
102 val v2 = ListPair.map var (us, (i+p) upto (i+length(ts)-2)) |
108 in list_comb(h,v1@[down ps u (i+length ts)]@v2) end; |
103 in list_comb(h,v1@[down ps u (i+length ts)]@v2) end; |
109 in Abs("", T, down (rev pos) t maxi) end; |
104 in Abs("", T, down (rev pos) t maxi) end; |
110 |
105 |
111 |
106 |
112 (************************************************************************ |
107 (************************************************************************ |
113 Set up term for instantiation of P in the split-theorem |
108 Set up term for instantiation of P in the split-theorem |
114 P(...) == rhs |
109 P(...) == rhs |
115 |
110 |
116 t : lefthand side of meta-equality in subgoal |
111 t : lefthand side of meta-equality in subgoal |
117 the split theorem is applied to (see select) |
112 the split theorem is applied to (see select) |
149 T : type of P(...) |
144 T : type of P(...) |
150 T' : type of term to be scanned |
145 T' : type of term to be scanned |
151 n : number of arguments expected by Const(key,...) |
146 n : number of arguments expected by Const(key,...) |
152 ts : list of arguments actually found |
147 ts : list of arguments actually found |
153 apsns : list of tuples of the form (T,U,pos), one tuple for each |
148 apsns : list of tuples of the form (T,U,pos), one tuple for each |
154 abstraction that is encountered on the way to the position where |
149 abstraction that is encountered on the way to the position where |
155 Const(key, ...) $ ... occurs, where |
150 Const(key, ...) $ ... occurs, where |
156 T : type of the variable bound by the abstraction |
151 T : type of the variable bound by the abstraction |
157 U : type of the abstraction's body |
152 U : type of the abstraction's body |
158 pos : "path" leading to the body of the abstraction |
153 pos : "path" leading to the body of the abstraction |
159 pos : "path" leading to the position where Const(key, ...) $ ... occurs. |
154 pos : "path" leading to the position where Const(key, ...) $ ... occurs. |
164 (thm, apsns, pos, TB, tt) |
159 (thm, apsns, pos, TB, tt) |
165 Note : apsns is reversed, so that the outermost quantifier's position |
160 Note : apsns is reversed, so that the outermost quantifier's position |
166 comes first ! If the terms in ts don't contain variables bound |
161 comes first ! If the terms in ts don't contain variables bound |
167 by other than meta-quantifiers, apsns is empty, because no further |
162 by other than meta-quantifiers, apsns is empty, because no further |
168 lifting is required before applying the split-theorem. |
163 lifting is required before applying the split-theorem. |
169 ******************************************************************************) |
164 ******************************************************************************) |
170 |
165 |
171 fun mk_split_pack(thm, T, T', n, ts, apsns, pos, TB, t) = |
166 fun mk_split_pack(thm, T, T', n, ts, apsns, pos, TB, t) = |
172 if n > length ts then [] |
167 if n > length ts then [] |
173 else let val lev = length apsns |
168 else let val lev = length apsns |
174 val lbnos = Library.foldl add_lbnos ([],Library.take(n,ts)) |
169 val lbnos = Library.foldl add_lbnos ([],Library.take(n,ts)) |
285 **************************************************************) |
280 **************************************************************) |
286 |
281 |
287 fun inst_lift Ts t (T, U, pos) state i = |
282 fun inst_lift Ts t (T, U, pos) state i = |
288 let |
283 let |
289 val cert = cterm_of (sign_of_thm state); |
284 val cert = cterm_of (sign_of_thm state); |
290 val cntxt = mk_cntxt Ts t pos (T --> U) (#maxidx(rep_thm trlift)); |
285 val cntxt = mk_cntxt Ts t pos (T --> U) (#maxidx(rep_thm trlift)); |
291 in cterm_instantiate [(cert P, cert cntxt)] trlift |
286 in cterm_instantiate [(cert P, cert cntxt)] trlift |
292 end; |
287 end; |
293 |
288 |
294 |
289 |
295 (************************************************************* |
290 (************************************************************* |
304 state : current proof state |
299 state : current proof state |
305 i : number of subgoal |
300 i : number of subgoal |
306 **************************************************************) |
301 **************************************************************) |
307 |
302 |
308 fun inst_split Ts t tt thm TB state i = |
303 fun inst_split Ts t tt thm TB state i = |
309 let |
304 let |
310 val thm' = Thm.lift_rule (state, i) thm; |
305 val thm' = Thm.lift_rule (state, i) thm; |
311 val (P, _) = strip_comb (fst (Logic.dest_equals |
306 val (P, _) = strip_comb (fst (Logic.dest_equals |
312 (Logic.strip_assums_concl (#prop (rep_thm thm'))))); |
307 (Logic.strip_assums_concl (#prop (rep_thm thm'))))); |
313 val cert = cterm_of (sign_of_thm state); |
308 val cert = cterm_of (sign_of_thm state); |
314 val cntxt = mk_cntxt_splitthm t tt TB; |
309 val cntxt = mk_cntxt_splitthm t tt TB; |
348 [] => compose_tac (false, inst_split Ts t tt thm TB state i, 0) i state |
343 [] => compose_tac (false, inst_split Ts t tt thm TB state i, 0) i state |
349 | p::_ => EVERY [lift_tac Ts t p, |
344 | p::_ => EVERY [lift_tac Ts t p, |
350 rtac reflexive_thm (i+1), |
345 rtac reflexive_thm (i+1), |
351 lift_split_tac] state) |
346 lift_split_tac] state) |
352 end |
347 end |
353 in COND (has_fewer_prems i) no_tac |
348 in COND (has_fewer_prems i) no_tac |
354 (rtac meta_iffD i THEN lift_split_tac) |
349 (rtac meta_iffD i THEN lift_split_tac) |
355 end; |
350 end; |
356 |
351 |
357 in split_tac end; |
352 in split_tac end; |
358 |
353 |
362 val split_inside_tac = mk_case_split_tac (rev_order o int_ord); |
357 val split_inside_tac = mk_case_split_tac (rev_order o int_ord); |
363 |
358 |
364 |
359 |
365 (***************************************************************************** |
360 (***************************************************************************** |
366 The split-tactic for premises |
361 The split-tactic for premises |
367 |
362 |
368 splits : list of split-theorems to be tried |
363 splits : list of split-theorems to be tried |
369 ****************************************************************************) |
364 ****************************************************************************) |
370 fun split_asm_tac [] = K no_tac |
365 fun split_asm_tac [] = K no_tac |
371 | split_asm_tac splits = |
366 | split_asm_tac splits = |
372 |
367 |
373 let val cname_list = map (fst o fst o split_thm_info) splits; |
368 let val cname_list = map (fst o fst o split_thm_info) splits; |
374 fun is_case (a,_) = a mem cname_list; |
369 fun is_case (a,_) = a mem cname_list; |
375 fun tac (t,i) = |
370 fun tac (t,i) = |
376 let val n = find_index (exists_Const is_case) |
371 let val n = find_index (exists_Const is_case) |
377 (Logic.strip_assums_hyp t); |
372 (Logic.strip_assums_hyp t); |
378 fun first_prem_is_disj (Const ("==>", _) $ (Const ("Trueprop", _) |
373 fun first_prem_is_disj (Const ("==>", _) $ (Const ("Trueprop", _) |
379 $ (Const (s, _) $ _ $ _ )) $ _ ) = (s=const_or) |
374 $ (Const (s, _) $ _ $ _ )) $ _ ) = (s=const_or) |
380 | first_prem_is_disj (Const("all",_)$Abs(_,_,t)) = |
375 | first_prem_is_disj (Const("all",_)$Abs(_,_,t)) = |
381 first_prem_is_disj t |
376 first_prem_is_disj t |
382 | first_prem_is_disj _ = false; |
377 | first_prem_is_disj _ = false; |
383 (* does not work properly if the split variable is bound by a quantfier *) |
378 (* does not work properly if the split variable is bound by a quantfier *) |
384 fun flat_prems_tac i = SUBGOAL (fn (t,i) => |
379 fun flat_prems_tac i = SUBGOAL (fn (t,i) => |
385 (if first_prem_is_disj t |
380 (if first_prem_is_disj t |
386 then EVERY[etac Data.disjE i,rotate_tac ~1 i, |
381 then EVERY[etac Data.disjE i,rotate_tac ~1 i, |
387 rotate_tac ~1 (i+1), |
382 rotate_tac ~1 (i+1), |
388 flat_prems_tac (i+1)] |
383 flat_prems_tac (i+1)] |
389 else all_tac) |
384 else all_tac) |
390 THEN REPEAT (eresolve_tac [Data.conjE,Data.exE] i) |
385 THEN REPEAT (eresolve_tac [Data.conjE,Data.exE] i) |
391 THEN REPEAT (dresolve_tac [Data.notnotD] i)) i; |
386 THEN REPEAT (dresolve_tac [Data.notnotD] i)) i; |
392 in if n<0 then no_tac else DETERM (EVERY' |
387 in if n<0 then no_tac else DETERM (EVERY' |
393 [rotate_tac n, etac Data.contrapos2, |
388 [rotate_tac n, etac Data.contrapos2, |
394 split_tac splits, |
389 split_tac splits, |
395 rotate_tac ~1, etac Data.contrapos, rotate_tac ~1, |
390 rotate_tac ~1, etac Data.contrapos, rotate_tac ~1, |
396 flat_prems_tac] i) |
391 flat_prems_tac] i) |
397 end; |
392 end; |
398 in SUBGOAL tac |
393 in SUBGOAL tac |
399 end; |
394 end; |
400 |
395 |
401 fun gen_split_tac [] = K no_tac |
396 fun gen_split_tac [] = K no_tac |
402 | gen_split_tac (split::splits) = |
397 | gen_split_tac (split::splits) = |
411 |
406 |
412 fun string_of_typ (Type (s, Ts)) = (if null Ts then "" |
407 fun string_of_typ (Type (s, Ts)) = (if null Ts then "" |
413 else enclose "(" ")" (commas (map string_of_typ Ts))) ^ s |
408 else enclose "(" ")" (commas (map string_of_typ Ts))) ^ s |
414 | string_of_typ _ = "_"; |
409 | string_of_typ _ = "_"; |
415 |
410 |
416 fun split_name (name, T) asm = "split " ^ |
411 fun split_name (name, T) asm = "split " ^ |
417 (if asm then "asm " else "") ^ name ^ " :: " ^ string_of_typ T; |
412 (if asm then "asm " else "") ^ name ^ " :: " ^ string_of_typ T; |
418 |
413 |
419 fun ss addsplits splits = |
414 fun ss addsplits splits = |
420 let fun addsplit (ss,split) = |
415 let fun addsplit (ss,split) = |
421 let val (name,asm) = split_thm_info split |
416 let val (name,asm) = split_thm_info split |
422 in Simplifier.addloop (ss, (split_name name asm, |
417 in Simplifier.addloop (ss, (split_name name asm, |
423 (if asm then split_asm_tac else split_tac) [split])) end |
418 (if asm then split_asm_tac else split_tac) [split])) end |
424 in Library.foldl addsplit (ss,splits) end; |
419 in Library.foldl addsplit (ss,splits) end; |
425 |
420 |
426 fun ss delsplits splits = |
421 fun ss delsplits splits = |
427 let fun delsplit(ss,split) = |
422 let fun delsplit(ss,split) = |
428 let val (name,asm) = split_thm_info split |
423 let val (name,asm) = split_thm_info split |
429 in Simplifier.delloop (ss, split_name name asm) |
424 in Simplifier.delloop (ss, split_name name asm) |
430 end in Library.foldl delsplit (ss,splits) end; |
425 end in Library.foldl delsplit (ss,splits) end; |
431 |
426 |
432 fun Addsplits splits = (Simplifier.simpset_ref() := |
427 fun Addsplits splits = (change_simpset (fn ss => ss addsplits splits)); |
433 Simplifier.simpset() addsplits splits); |
428 fun Delsplits splits = (change_simpset (fn ss => ss delsplits splits)); |
434 fun Delsplits splits = (Simplifier.simpset_ref() := |
|
435 Simplifier.simpset() delsplits splits); |
|
436 |
429 |
437 |
430 |
438 (* attributes *) |
431 (* attributes *) |
439 |
432 |
440 val splitN = "split"; |
433 val splitN = "split"; |