13 signature SUBGOAL = |
13 signature SUBGOAL = |
14 sig |
14 sig |
15 type focus = |
15 type focus = |
16 {context: Proof.context, params: (string * cterm) list, prems: thm list, asms: cterm list, |
16 {context: Proof.context, params: (string * cterm) list, prems: thm list, asms: cterm list, |
17 concl: cterm, schematics: ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list} |
17 concl: cterm, schematics: ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list} |
18 val focus_params: Proof.context -> int -> thm -> focus * thm |
18 val focus_params: Proof.context -> int -> binding list option -> thm -> focus * thm |
19 val focus_params_fixed: Proof.context -> int -> thm -> focus * thm |
19 val focus_params_fixed: Proof.context -> int -> binding list option -> thm -> focus * thm |
20 val focus_prems: Proof.context -> int -> thm -> focus * thm |
20 val focus_prems: Proof.context -> int -> binding list option -> thm -> focus * thm |
21 val focus: Proof.context -> int -> thm -> focus * thm |
21 val focus: Proof.context -> int -> binding list option -> thm -> focus * thm |
22 val retrofit: Proof.context -> Proof.context -> (string * cterm) list -> cterm list -> |
22 val retrofit: Proof.context -> Proof.context -> (string * cterm) list -> cterm list -> |
23 int -> thm -> thm -> thm Seq.seq |
23 int -> thm -> thm -> thm Seq.seq |
24 val FOCUS_PARAMS: (focus -> tactic) -> Proof.context -> int -> tactic |
24 val FOCUS_PARAMS: (focus -> tactic) -> Proof.context -> int -> tactic |
25 val FOCUS_PARAMS_FIXED: (focus -> tactic) -> Proof.context -> int -> tactic |
25 val FOCUS_PARAMS_FIXED: (focus -> tactic) -> Proof.context -> int -> tactic |
26 val FOCUS_PREMS: (focus -> tactic) -> Proof.context -> int -> tactic |
26 val FOCUS_PREMS: (focus -> tactic) -> Proof.context -> int -> tactic |
39 |
39 |
40 type focus = |
40 type focus = |
41 {context: Proof.context, params: (string * cterm) list, prems: thm list, asms: cterm list, |
41 {context: Proof.context, params: (string * cterm) list, prems: thm list, asms: cterm list, |
42 concl: cterm, schematics: ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list}; |
42 concl: cterm, schematics: ((indexname * sort) * ctyp) list * ((indexname * typ) * cterm) list}; |
43 |
43 |
44 fun gen_focus (do_prems, do_concl) ctxt i raw_st = |
44 fun gen_focus (do_prems, do_concl) ctxt i bindings raw_st = |
45 let |
45 let |
46 val st = raw_st |
46 val st = raw_st |
47 |> Thm.transfer (Proof_Context.theory_of ctxt) |
47 |> Thm.transfer (Proof_Context.theory_of ctxt) |
48 |> Raw_Simplifier.norm_hhf_protect ctxt; |
48 |> Raw_Simplifier.norm_hhf_protect ctxt; |
49 val ((schematic_types, [st']), ctxt1) = Variable.importT [st] ctxt; |
49 val ((schematic_types, [st']), ctxt1) = Variable.importT [st] ctxt; |
50 val ((params, goal), ctxt2) = Variable.focus_cterm (Thm.cprem_of st' i) ctxt1; |
50 val ((params, goal), ctxt2) = Variable.focus_cterm bindings (Thm.cprem_of st' i) ctxt1; |
51 |
51 |
52 val (asms, concl) = |
52 val (asms, concl) = |
53 if do_prems then (Drule.strip_imp_prems goal, Drule.strip_imp_concl goal) |
53 if do_prems then (Drule.strip_imp_prems goal, Drule.strip_imp_concl goal) |
54 else ([], goal); |
54 else ([], goal); |
55 val text = asms @ (if do_concl then [concl] else []); |
55 val text = asms @ (if do_concl then [concl] else []); |
148 (* tacticals *) |
148 (* tacticals *) |
149 |
149 |
150 fun GEN_FOCUS flags tac ctxt i st = |
150 fun GEN_FOCUS flags tac ctxt i st = |
151 if Thm.nprems_of st < i then Seq.empty |
151 if Thm.nprems_of st < i then Seq.empty |
152 else |
152 else |
153 let val (args as {context = ctxt', params, asms, ...}, st') = gen_focus flags ctxt i st; |
153 let val (args as {context = ctxt', params, asms, ...}, st') = gen_focus flags ctxt i NONE st; |
154 in Seq.lifts (retrofit ctxt' ctxt params asms i) (tac args st') st end; |
154 in Seq.lifts (retrofit ctxt' ctxt params asms i) (tac args st') st end; |
155 |
155 |
156 val FOCUS_PARAMS = GEN_FOCUS (false, false); |
156 val FOCUS_PARAMS = GEN_FOCUS (false, false); |
157 val FOCUS_PARAMS_FIXED = GEN_FOCUS (false, true); |
157 val FOCUS_PARAMS_FIXED = GEN_FOCUS (false, true); |
158 val FOCUS_PREMS = GEN_FOCUS (true, false); |
158 val FOCUS_PREMS = GEN_FOCUS (true, false); |
163 |
163 |
164 (* Isar subgoal command *) |
164 (* Isar subgoal command *) |
165 |
165 |
166 local |
166 local |
167 |
167 |
168 fun rename_params ctxt (param_suffix, raw_param_specs) st = |
168 fun param_bindings ctxt (param_suffix, raw_param_specs) st = |
169 let |
169 let |
170 val _ = if Thm.no_prems st then error "No subgoals!" else (); |
170 val _ = if Thm.no_prems st then error "No subgoals!" else (); |
171 val (subgoal, goal') = Logic.dest_implies (Thm.prop_of st); |
171 val subgoal = #1 (Logic.dest_implies (Thm.prop_of st)); |
172 val subgoal_params = |
172 val subgoal_params = |
173 map (apfst (Name.internal o Name.clean)) (Term.strip_all_vars subgoal) |
173 map (apfst (Name.internal o Name.clean)) (Term.strip_all_vars subgoal) |
174 |> Term.variant_frees subgoal |> map #1; |
174 |> Term.variant_frees subgoal |> map #1; |
175 |
175 |
176 val n = length subgoal_params; |
176 val n = length subgoal_params; |
182 |
182 |
183 val param_specs = |
183 val param_specs = |
184 raw_param_specs |> map |
184 raw_param_specs |> map |
185 (fn (NONE, _) => NONE |
185 (fn (NONE, _) => NONE |
186 | (SOME x, pos) => |
186 | (SOME x, pos) => |
187 let val b = #1 (#1 (Proof_Context.cert_var (Binding.make (x, pos), NONE, NoSyn) ctxt)) |
187 let |
188 in SOME (Variable.check_name b) end) |
188 val b = #1 (#1 (Proof_Context.cert_var (Binding.make (x, pos), NONE, NoSyn) ctxt)); |
|
189 val _ = Variable.check_name b; |
|
190 in SOME b end) |
189 |> param_suffix ? append (replicate (n - m) NONE); |
191 |> param_suffix ? append (replicate (n - m) NONE); |
190 |
192 |
191 fun rename_list (opt_x :: xs) (y :: ys) = (the_default y opt_x :: rename_list xs ys) |
193 fun bindings (SOME x :: xs) (_ :: ys) = x :: bindings xs ys |
192 | rename_list _ ys = ys; |
194 | bindings (NONE :: xs) (y :: ys) = Binding.name y :: bindings xs ys |
193 |
195 | bindings _ ys = map Binding.name ys; |
194 fun rename_prop (x :: xs) ((c as Const ("Pure.all", _)) $ Abs (_, T, t)) = |
196 in bindings param_specs subgoal_params end; |
195 (c $ Abs (x, T, rename_prop xs t)) |
|
196 | rename_prop [] t = t; |
|
197 |
|
198 val subgoal' = rename_prop (rename_list param_specs subgoal_params) subgoal; |
|
199 in Thm.renamed_prop (Logic.mk_implies (subgoal', goal')) st end; |
|
200 |
197 |
201 fun gen_subgoal prep_atts raw_result_binding raw_prems_binding param_specs state = |
198 fun gen_subgoal prep_atts raw_result_binding raw_prems_binding param_specs state = |
202 let |
199 let |
203 val _ = Proof.assert_backward state; |
200 val _ = Proof.assert_backward state; |
204 |
201 |
210 (case raw_prems_binding of |
207 (case raw_prems_binding of |
211 SOME (b, raw_atts) => ((b, map (prep_atts ctxt) raw_atts), true) |
208 SOME (b, raw_atts) => ((b, map (prep_atts ctxt) raw_atts), true) |
212 | NONE => ((Binding.empty, []), false)); |
209 | NONE => ((Binding.empty, []), false)); |
213 |
210 |
214 val (subgoal_focus, _) = |
211 val (subgoal_focus, _) = |
215 rename_params ctxt param_specs st |
212 (if do_prems then focus else focus_params_fixed) ctxt |
216 |> (if do_prems then focus else focus_params_fixed) ctxt 1; |
213 1 (SOME (param_bindings ctxt param_specs st)) st; |
217 |
214 |
218 fun after_qed (ctxt'', [[result]]) = |
215 fun after_qed (ctxt'', [[result]]) = |
219 Proof.end_block #> (fn state' => |
216 Proof.end_block #> (fn state' => |
220 let |
217 let |
221 val ctxt' = Proof.context_of state'; |
218 val ctxt' = Proof.context_of state'; |