97 let |
85 let |
98 val thy = Proof_Context.theory_of ctxt; |
86 val thy = Proof_Context.theory_of ctxt; |
99 val cert = Thm.cterm_of thy; |
87 val cert = Thm.cterm_of thy; |
100 val certT = Thm.ctyp_of thy; |
88 val certT = Thm.ctyp_of thy; |
101 |
89 |
102 val (type_insts, term_insts) = List.partition (is_tvar o fst) mixed_insts; |
90 val (type_insts, term_insts) = List.partition (String.isPrefix "'" o fst o fst) mixed_insts; |
103 val internal_insts = term_insts |> map_filter |
91 |
104 (fn (xi, Token.Term t) => SOME (xi, t) |
92 |
105 | (_, Token.Text _) => NONE |
93 (* type instantiations *) |
106 | (xi, _) => error_var "Term argument expected for " xi); |
94 |
107 val external_insts = term_insts |> map_filter |
95 fun readT (xi, s) = |
108 (fn (xi, Token.Text s) => SOME (xi, s) | _ => NONE); |
|
109 |
|
110 |
|
111 (* mixed type instantiations *) |
|
112 |
|
113 fun readT (xi, arg) = |
|
114 let |
96 let |
115 val S = the_sort tvars xi; |
97 val S = the_sort tvars xi; |
116 val T = |
98 val T = Syntax.read_typ ctxt s; |
117 (case arg of |
|
118 Token.Text s => Syntax.read_typ ctxt s |
|
119 | Token.Typ T => T |
|
120 | _ => error_var "Type argument expected for " xi); |
|
121 in |
99 in |
122 if Sign.of_sort thy (T, S) then ((xi, S), T) |
100 if Sign.of_sort thy (T, S) then ((xi, S), T) |
123 else error_var "Incompatible sort for typ instantiation of " xi |
101 else error_var "Incompatible sort for typ instantiation of " xi |
124 end; |
102 end; |
125 |
103 |
126 val type_insts1 = map readT type_insts; |
104 val instT1 = Term_Subst.instantiateT (map readT type_insts); |
127 val instT1 = Term_Subst.instantiateT type_insts1; |
|
128 val vars1 = map (apsnd instT1) vars; |
105 val vars1 = map (apsnd instT1) vars; |
129 |
106 |
130 |
107 |
131 (* internal term instantiations *) |
108 (* term instantiations *) |
132 |
109 |
133 val instT2 = Envir.norm_type |
110 val (xs, ss) = split_list term_insts; |
134 (#1 (fold (unify_vartypes thy vars1) internal_insts (Vartab.empty, 0))); |
111 val Ts = map (the_type vars1) xs; |
|
112 val (ts, inferred) = read_termTs ctxt false ss Ts; |
|
113 |
|
114 val instT2 = Term.typ_subst_TVars inferred; |
135 val vars2 = map (apsnd instT2) vars1; |
115 val vars2 = map (apsnd instT2) vars1; |
136 val internal_insts2 = map (apsnd (map_types instT2)) internal_insts; |
116 val inst2 = instantiate (xs ~~ ts); |
137 val inst2 = instantiate internal_insts2; |
117 |
138 |
118 |
139 |
119 (* result *) |
140 (* external term instantiations *) |
120 |
141 |
121 val inst_tvars = map_filter (make_instT (instT2 o instT1)) tvars; |
142 val (xs, strs) = split_list external_insts; |
122 val inst_vars = map_filter (make_inst inst2) vars2; |
143 val Ts = map (the_type vars2) xs; |
|
144 val (ts, inferred) = read_termTs ctxt false strs Ts; |
|
145 |
|
146 val instT3 = Term.typ_subst_TVars inferred; |
|
147 val vars3 = map (apsnd instT3) vars2; |
|
148 val internal_insts3 = map (apsnd (map_types instT3)) internal_insts2; |
|
149 val external_insts3 = xs ~~ ts; |
|
150 val inst3 = instantiate external_insts3; |
|
151 |
|
152 |
|
153 (* results *) |
|
154 |
|
155 val type_insts3 = map (fn ((a, _), T) => (a, instT3 (instT2 T))) type_insts1; |
|
156 val term_insts3 = internal_insts3 @ external_insts3; |
|
157 |
|
158 val inst_tvars = map_filter (make_instT (instT3 o instT2 o instT1)) tvars; |
|
159 val inst_vars = map_filter (make_inst (inst3 o inst2)) vars3; |
|
160 in |
123 in |
161 ((type_insts3, term_insts3), |
124 (map (pairself certT) inst_tvars, map (pairself cert) inst_vars) |
162 (map (pairself certT) inst_tvars, map (pairself cert) inst_vars)) |
|
163 end; |
125 end; |
164 |
126 |
165 fun read_instantiate_mixed ctxt mixed_insts thm = |
127 fun read_instantiate_mixed ctxt mixed_insts thm = |
166 let |
128 let |
167 val ctxt' = ctxt |> Variable.declare_thm thm |
129 val ctxt' = ctxt |
168 |> fold (fn a => Variable.declare_names (Logic.mk_type (TFree (a, dummyS)))) (add_used thm []); (* FIXME tmp *) |
130 |> Variable.declare_thm thm |
|
131 |> fold (fn a => Variable.declare_names (Logic.mk_type (TFree (a, dummyS)))) (add_used thm []); (* FIXME !? *) |
169 val tvars = Thm.fold_terms Term.add_tvars thm []; |
132 val tvars = Thm.fold_terms Term.add_tvars thm []; |
170 val vars = Thm.fold_terms Term.add_vars thm []; |
133 val vars = Thm.fold_terms Term.add_vars thm []; |
171 val ((type_insts, term_insts), insts) = read_insts ctxt' (map snd mixed_insts) (tvars, vars); |
134 val insts = read_insts ctxt' mixed_insts (tvars, vars); |
172 |
|
173 val _ = (*assign internalized values*) |
|
174 mixed_insts |> List.app (fn (arg, (xi, _)) => |
|
175 if is_tvar xi then |
|
176 Token.assign (SOME (Token.Typ (the (AList.lookup (op =) type_insts xi)))) arg |
|
177 else |
|
178 Token.assign (SOME (Token.Term (the (AList.lookup (op =) term_insts xi)))) arg); |
|
179 in |
135 in |
180 Drule.instantiate_normalize insts thm |> Rule_Cases.save thm |
136 Drule.instantiate_normalize insts thm |
|
137 |> Rule_Cases.save thm |
181 end; |
138 end; |
182 |
139 |
183 fun read_instantiate_mixed' ctxt (args, concl_args) thm = |
140 fun read_instantiate_mixed' ctxt (args, concl_args) thm = |
184 let |
141 let |
185 fun zip_vars _ [] = [] |
142 fun zip_vars _ [] = [] |
186 | zip_vars (_ :: xs) ((_, NONE) :: rest) = zip_vars xs rest |
143 | zip_vars (_ :: xs) (NONE :: rest) = zip_vars xs rest |
187 | zip_vars ((x, _) :: xs) ((arg, SOME t) :: rest) = (arg, (x, t)) :: zip_vars xs rest |
144 | zip_vars ((x, _) :: xs) (SOME t :: rest) = (x, t) :: zip_vars xs rest |
188 | zip_vars [] _ = error "More instantiations than variables in theorem"; |
145 | zip_vars [] _ = error "More instantiations than variables in theorem"; |
189 val insts = |
146 val insts = |
190 zip_vars (rev (Term.add_vars (Thm.full_prop_of thm) [])) args @ |
147 zip_vars (rev (Term.add_vars (Thm.full_prop_of thm) [])) args @ |
191 zip_vars (rev (Term.add_vars (Thm.concl_of thm) [])) concl_args; |
148 zip_vars (rev (Term.add_vars (Thm.concl_of thm) [])) concl_args; |
192 in read_instantiate_mixed ctxt insts thm end; |
149 in read_instantiate_mixed ctxt insts thm end; |
194 end; |
151 end; |
195 |
152 |
196 |
153 |
197 (* instantiation of rule or goal state *) |
154 (* instantiation of rule or goal state *) |
198 |
155 |
199 fun read_instantiate ctxt args thm = |
156 fun read_instantiate ctxt = |
200 read_instantiate_mixed (ctxt |> Proof_Context.set_mode Proof_Context.mode_schematic) (* FIXME !? *) |
157 read_instantiate_mixed (ctxt |> Proof_Context.set_mode Proof_Context.mode_schematic); (* FIXME !? *) |
201 (map (fn (x, y) => (Token.eof, (x, Token.Text y))) args) thm; |
|
202 |
158 |
203 fun instantiate_tac ctxt args = PRIMITIVE (read_instantiate ctxt args); |
159 fun instantiate_tac ctxt args = PRIMITIVE (read_instantiate ctxt args); |
204 |
160 |
205 |
161 |
206 |
162 |
207 (** attributes **) |
163 (** attributes **) |
208 |
164 |
209 (* where: named instantiation *) |
165 (* where: named instantiation *) |
210 |
|
211 local |
|
212 |
|
213 val value = |
|
214 Args.internal_typ >> Token.Typ || |
|
215 Args.internal_term >> Token.Term || |
|
216 Args.name_source >> Token.Text; |
|
217 |
|
218 val inst = Args.var -- (Args.$$$ "=" |-- Scan.ahead Parse.not_eof -- value) |
|
219 >> (fn (xi, (a, v)) => (a, (xi, v))); |
|
220 |
|
221 in |
|
222 |
166 |
223 val _ = Context.>> (Context.map_theory |
167 val _ = Context.>> (Context.map_theory |
224 (Attrib.setup (Binding.name "where") |
168 (Attrib.setup (Binding.name "where") |
225 (Scan.lift (Parse.and_list inst) >> (fn args => |
169 (Scan.lift (Parse.and_list (Args.var -- (Args.$$$ "=" |-- Args.name_source))) >> |
226 Thm.rule_attribute (fn context => read_instantiate_mixed (Context.proof_of context) args))) |
170 (fn args => |
|
171 Thm.rule_attribute (fn context => read_instantiate_mixed (Context.proof_of context) args))) |
227 "named instantiation of theorem")); |
172 "named instantiation of theorem")); |
228 |
173 |
229 end; |
|
230 |
|
231 |
174 |
232 (* of: positional instantiation (terms only) *) |
175 (* of: positional instantiation (terms only) *) |
233 |
176 |
234 local |
177 local |
235 |
178 |
236 val value = |
179 val inst = Args.maybe Args.name_source; |
237 Args.internal_term >> Token.Term || |
|
238 Args.name_source >> Token.Text; |
|
239 |
|
240 val inst = Scan.ahead Parse.not_eof -- Args.maybe value; |
|
241 val concl = Args.$$$ "concl" -- Args.colon; |
180 val concl = Args.$$$ "concl" -- Args.colon; |
242 |
181 |
243 val insts = |
182 val insts = |
244 Scan.repeat (Scan.unless concl inst) -- |
183 Scan.repeat (Scan.unless concl inst) -- |
245 Scan.optional (concl |-- Scan.repeat inst) []; |
184 Scan.optional (concl |-- Scan.repeat inst) []; |