68 (*rewrite conclusion with k-th assumtion*) |
68 (*rewrite conclusion with k-th assumtion*) |
69 fun rewrite_with_asm_tac ctxt k = |
69 fun rewrite_with_asm_tac ctxt k = |
70 Subgoal.FOCUS (fn {context = ctxt', prems, ...} => |
70 Subgoal.FOCUS (fn {context = ctxt', prems, ...} => |
71 Local_Defs.unfold_tac ctxt' [nth prems k]) ctxt; |
71 Local_Defs.unfold_tac ctxt' [nth prems k]) ctxt; |
72 |
72 |
73 fun dest_case thy t = |
73 fun dest_case ctxt t = |
74 case strip_comb t of |
74 case strip_comb t of |
75 (Const (case_comb, _), args) => |
75 (Const (case_comb, _), args) => |
76 (case Datatype.info_of_case thy case_comb of |
76 (case Ctr_Sugar.ctr_sugar_of_case ctxt case_comb of |
77 NONE => NONE |
77 NONE => NONE |
78 | SOME {case_rewrites, ...} => |
78 | SOME {case_thms, ...} => |
79 let |
79 let |
80 val lhs = prop_of (hd case_rewrites) |
80 val lhs = prop_of (hd case_thms) |
81 |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> fst; |
81 |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> fst; |
82 val arity = length (snd (strip_comb lhs)); |
82 val arity = length (snd (strip_comb lhs)); |
83 val conv = funpow (length args - arity) Conv.fun_conv |
83 val conv = funpow (length args - arity) Conv.fun_conv |
84 (Conv.rewrs_conv (map mk_meta_eq case_rewrites)); |
84 (Conv.rewrs_conv (map mk_meta_eq case_thms)); |
85 in |
85 in |
86 SOME (nth args (arity - 1), conv) |
86 SOME (nth args (arity - 1), conv) |
87 end) |
87 end) |
88 | _ => NONE; |
88 | _ => NONE; |
89 |
89 |
90 (*split on case expressions*) |
90 (*split on case expressions*) |
91 val split_cases_tac = Subgoal.FOCUS_PARAMS (fn {context=ctxt, ...} => |
91 val split_cases_tac = Subgoal.FOCUS_PARAMS (fn {context=ctxt, ...} => |
92 SUBGOAL (fn (t, i) => case t of |
92 SUBGOAL (fn (t, i) => case t of |
93 _ $ (_ $ Abs (_, _, body)) => |
93 _ $ (_ $ Abs (_, _, body)) => |
94 (case dest_case (Proof_Context.theory_of ctxt) body of |
94 (case dest_case ctxt body of |
95 NONE => no_tac |
95 NONE => no_tac |
96 | SOME (arg, conv) => |
96 | SOME (arg, conv) => |
97 let open Conv in |
97 let open Conv in |
98 if Term.is_open arg then no_tac |
98 if Term.is_open arg then no_tac |
99 else ((DETERM o strip_cases o Induct.cases_tac ctxt false [[SOME arg]] NONE []) |
99 else ((DETERM o strip_cases o Induct.cases_tac ctxt false [[SOME arg]] NONE []) |