69 val _ = null bads orelse |
69 val _ = null bads orelse |
70 error ("Result contains obtained parameters: " ^ |
70 error ("Result contains obtained parameters: " ^ |
71 space_implode " " (map (Syntax.string_of_term ctxt) bads)); |
71 space_implode " " (map (Syntax.string_of_term ctxt) bads)); |
72 in tm end; |
72 in tm end; |
73 |
73 |
74 fun eliminate fix_ctxt rule xs As thm = |
74 fun eliminate ctxt rule xs As thm = |
75 let |
75 let |
76 val _ = eliminate_term fix_ctxt xs (Thm.full_prop_of thm); |
76 val _ = eliminate_term ctxt xs (Thm.full_prop_of thm); |
77 val _ = Object_Logic.is_judgment fix_ctxt (Thm.concl_of thm) orelse |
77 val _ = Object_Logic.is_judgment ctxt (Thm.concl_of thm) orelse |
78 error "Conclusion in obtained context must be object-logic judgment"; |
78 error "Conclusion in obtained context must be object-logic judgment"; |
79 |
79 |
80 val ((_, [thm']), ctxt') = Variable.import true [thm] fix_ctxt; |
80 val ((_, [thm']), ctxt') = Variable.import true [thm] ctxt; |
81 val prems = Drule.strip_imp_prems (#prop (Thm.crep_thm thm')); |
81 val prems = Drule.strip_imp_prems (#prop (Thm.crep_thm thm')); |
82 in |
82 in |
83 ((Drule.implies_elim_list thm' (map Thm.assume prems) |
83 ((Drule.implies_elim_list thm' (map Thm.assume prems) |
84 |> Drule.implies_intr_list (map (Drule.norm_hhf_cterm ctxt') As) |
84 |> Drule.implies_intr_list (map (Drule.norm_hhf_cterm ctxt') As) |
85 |> Drule.forall_intr_list xs) |
85 |> Drule.forall_intr_list xs) |
86 COMP rule) |
86 COMP rule) |
87 |> Drule.implies_intr_list prems |
87 |> Drule.implies_intr_list prems |
88 |> singleton (Variable.export ctxt' fix_ctxt) |
88 |> singleton (Variable.export ctxt' ctxt) |
89 end; |
89 end; |
90 |
90 |
91 fun obtain_export ctxt rule xs _ As = |
91 fun obtain_export ctxt rule xs _ As = |
92 (eliminate ctxt rule xs As, eliminate_term ctxt xs); |
92 (eliminate ctxt rule xs As, eliminate_term ctxt xs); |
93 |
93 |
116 val (vars, vars_ctxt) = fold_map prep_var raw_vars ctxt; |
116 val (vars, vars_ctxt) = fold_map prep_var raw_vars ctxt; |
117 val (xs', fix_ctxt) = vars_ctxt |> Proof_Context.add_fixes vars; |
117 val (xs', fix_ctxt) = vars_ctxt |> Proof_Context.add_fixes vars; |
118 val xs = map (Variable.check_name o #1) vars; |
118 val xs = map (Variable.check_name o #1) vars; |
119 |
119 |
120 (*obtain asms*) |
120 (*obtain asms*) |
121 val (proppss, asms_ctxt) = prep_propp (map snd raw_asms) fix_ctxt; |
121 val ((propss, binds), props_ctxt) = prep_propp (map snd raw_asms) fix_ctxt; |
122 val ((_, binds), binds_ctxt) = Proof_Context.bind_propp proppss asms_ctxt; |
122 val props = flat propss; |
123 val asm_props = maps (map fst) proppss; |
123 val asms = |
124 val asms = map fst (Attrib.map_specs (map (prep_att ctxt)) raw_asms) ~~ proppss; |
124 map (fn ((b, raw_atts), _) => (b, map (prep_att ctxt) raw_atts)) raw_asms ~~ |
125 |
125 unflat propss (map (rpair []) props); |
126 (*obtain parms*) |
126 |
127 val (Ts, parms_ctxt) = fold_map Proof_Context.inferred_param xs' asms_ctxt; |
127 (*obtain params*) |
128 val parms = map Free (xs' ~~ Ts); |
128 val (Ts, params_ctxt) = fold_map Proof_Context.inferred_param xs' props_ctxt; |
129 val cparms = map (Thm.cterm_of ctxt) parms; |
129 val params = map Free (xs' ~~ Ts); |
130 val _ = Variable.warn_extra_tfrees fix_ctxt parms_ctxt; |
130 val cparams = map (Thm.cterm_of params_ctxt) params; |
|
131 val _ = Variable.warn_extra_tfrees fix_ctxt params_ctxt; |
|
132 |
|
133 (*abstracted term bindings*) |
|
134 fun abs_params t = |
|
135 let |
|
136 val ps = |
|
137 (xs ~~ params) |> map_filter (fn (x, p) => |
|
138 if exists_subterm (fn u => u aconv p) t then SOME (x, p) else NONE); |
|
139 in fold_rev Term.lambda_name ps t end; |
|
140 val binds' = map (apsnd (Term.close_schematic_term o abs_params)) binds; |
131 |
141 |
132 (*obtain statements*) |
142 (*obtain statements*) |
133 val thesisN = singleton (Name.variant_list xs) Auto_Bind.thesisN; |
143 val thesisN = singleton (Name.variant_list xs) Auto_Bind.thesisN; |
134 val (thesis_var, thesis) = #1 (bind_judgment fix_ctxt thesisN); |
144 val (thesis_var, thesis) = #1 (bind_judgment fix_ctxt thesisN); |
135 |
145 |
136 val that_name = if name = "" then thatN else name; |
146 val that_name = if name = "" then thatN else name; |
137 val that_prop = |
147 val that_prop = |
138 Logic.list_rename_params xs |
148 Logic.list_rename_params xs |
139 (fold_rev Logic.all parms (Logic.list_implies (asm_props, thesis))); |
149 (fold_rev Logic.all params (Logic.list_implies (props, thesis))); |
140 val obtain_prop = |
150 val obtain_prop = |
141 Logic.list_rename_params [Auto_Bind.thesisN] |
151 Logic.list_rename_params [Auto_Bind.thesisN] |
142 (Logic.all (Free thesis_var) (Logic.mk_implies (that_prop, thesis))); |
152 (Logic.all (Free thesis_var) (Logic.mk_implies (that_prop, thesis))); |
143 |
153 |
144 fun after_qed _ = |
154 fun after_qed _ = |
145 Proof.local_qed (NONE, false) |
155 Proof.local_qed (NONE, false) |
146 #> `Proof.the_fact #-> (fn rule => |
156 #> `Proof.the_fact #-> (fn rule => |
147 Proof.fix vars |
157 Proof.fix vars |
148 #> Proof.assm (obtain_export fix_ctxt rule cparms) asms); |
158 #> Proof.map_context (Proof_Context.bind_terms binds) |
|
159 #> Proof.assm (obtain_export params_ctxt rule cparams) asms); |
149 in |
160 in |
150 state |
161 state |
151 |> Proof.enter_forward |
162 |> Proof.enter_forward |
152 |> Proof.have NONE (K I) [(Thm.empty_binding, [(obtain_prop, [])])] int |
163 |> Proof.have NONE (K I) [(Thm.empty_binding, [(obtain_prop, [])])] int |
153 |> Proof.map_context (Proof_Context.export_bind_terms binds binds_ctxt) |
164 |> Proof.map_context (Proof_Context.bind_terms binds') |
154 |> Proof.proof (SOME Method.succeed_text) |> Seq.hd |
165 |> Proof.proof (SOME Method.succeed_text) |> Seq.hd |
155 |> Proof.fix [(Binding.name thesisN, NONE, NoSyn)] |
166 |> Proof.fix [(Binding.name thesisN, NONE, NoSyn)] |
156 |> Proof.assume |
167 |> Proof.assume |
157 [((Binding.name that_name, [Context_Rules.intro_query NONE]), [(that_prop, [])])] |
168 [((Binding.name that_name, [Context_Rules.intro_query NONE]), [(that_prop, [])])] |
158 |> `Proof.the_facts |
169 |> `Proof.the_facts |