78 SOME (nth args (arity - 1), conv) |
78 SOME (nth args (arity - 1), conv) |
79 end) |
79 end) |
80 | _ => NONE; |
80 | _ => NONE; |
81 |
81 |
82 (*split on case expressions*) |
82 (*split on case expressions*) |
83 val split_cases_tac = Subgoal.FOCUS_PARAMS (fn {context=ctxt, ...} => |
83 val split_cases_tac = Subgoal.FOCUS_PARAMS (fn {context = ctxt, ...} => |
84 SUBGOAL (fn (t, i) => case t of |
84 SUBGOAL (fn (t, i) => case t of |
85 _ $ (_ $ Abs (_, _, body)) => |
85 _ $ (_ $ Abs (_, _, body)) => |
86 (case dest_case ctxt body of |
86 (case dest_case ctxt body of |
87 NONE => no_tac |
87 NONE => no_tac |
88 | SOME (arg, conv) => |
88 | SOME (arg, conv) => |
89 let open Conv in |
89 let open Conv in |
90 if Term.is_open arg then no_tac |
90 if Term.is_open arg then no_tac |
91 else ((DETERM o strip_cases o Induct.cases_tac ctxt false [[SOME arg]] NONE []) |
91 else ((DETERM o strip_cases o Induct.cases_tac ctxt false [[SOME arg]] NONE []) |
92 THEN_ALL_NEW (rewrite_with_asm_tac ctxt 0) |
92 THEN_ALL_NEW (rewrite_with_asm_tac ctxt 0) |
93 THEN_ALL_NEW eresolve_tac @{thms thin_rl} |
93 THEN_ALL_NEW eresolve_tac ctxt @{thms thin_rl} |
94 THEN_ALL_NEW (CONVERSION |
94 THEN_ALL_NEW (CONVERSION |
95 (params_conv ~1 (fn ctxt' => |
95 (params_conv ~1 (fn ctxt' => |
96 arg_conv (arg_conv (abs_conv (K conv) ctxt'))) ctxt))) i |
96 arg_conv (arg_conv (abs_conv (K conv) ctxt'))) ctxt))) i |
97 end) |
97 end) |
98 | _ => no_tac) 1); |
98 | _ => no_tac) 1); |
99 |
99 |
100 (*monotonicity proof: apply rules + split case expressions*) |
100 (*monotonicity proof: apply rules + split case expressions*) |
101 fun mono_tac ctxt = |
101 fun mono_tac ctxt = |
102 K (Local_Defs.unfold_tac ctxt [@{thm curry_def}]) |
102 K (Local_Defs.unfold_tac ctxt [@{thm curry_def}]) |
103 THEN' (TRY o REPEAT_ALL_NEW |
103 THEN' (TRY o REPEAT_ALL_NEW |
104 (resolve_tac (rev (Named_Theorems.get ctxt @{named_theorems partial_function_mono})) |
104 (resolve_tac ctxt (rev (Named_Theorems.get ctxt @{named_theorems partial_function_mono})) |
105 ORELSE' split_cases_tac ctxt)); |
105 ORELSE' split_cases_tac ctxt)); |
106 |
106 |
107 |
107 |
108 (*** Auxiliary functions ***) |
108 (*** Auxiliary functions ***) |
109 |
109 |
288 |
288 |
289 val raw_induct = Option.map mk_raw_induct fixp_induct_user |
289 val raw_induct = Option.map mk_raw_induct fixp_induct_user |
290 val rec_rule = let open Conv in |
290 val rec_rule = let open Conv in |
291 Goal.prove lthy' (map (fst o dest_Free) args) [] eqn (fn _ => |
291 Goal.prove lthy' (map (fst o dest_Free) args) [] eqn (fn _ => |
292 CONVERSION ((arg_conv o arg1_conv o head_conv o rewr_conv) (mk_meta_eq unfold)) 1 |
292 CONVERSION ((arg_conv o arg1_conv o head_conv o rewr_conv) (mk_meta_eq unfold)) 1 |
293 THEN resolve_tac @{thms refl} 1) end; |
293 THEN resolve_tac lthy' @{thms refl} 1) end; |
294 in |
294 in |
295 lthy' |
295 lthy' |
296 |> Local_Theory.note (eq_abinding, [rec_rule]) |
296 |> Local_Theory.note (eq_abinding, [rec_rule]) |
297 |-> (fn (_, rec') => |
297 |-> (fn (_, rec') => |
298 Spec_Rules.add Spec_Rules.Equational ([f], rec') |
298 Spec_Rules.add Spec_Rules.Equational ([f], rec') |