46 val partition_insts = List.partition (fn (((x, _), _), _) => String.isPrefix "'" x); |
46 val partition_insts = List.partition (fn (((x, _), _), _) => String.isPrefix "'" x); |
47 |
47 |
48 fun error_var msg (xi, pos) = |
48 fun error_var msg (xi, pos) = |
49 error (msg ^ quote (Term.string_of_vname xi) ^ Position.here pos); |
49 error (msg ^ quote (Term.string_of_vname xi) ^ Position.here pos); |
50 |
50 |
51 local |
|
52 |
|
53 fun the_sort tvars (xi, pos) : sort = |
51 fun the_sort tvars (xi, pos) : sort = |
54 (case AList.lookup (op =) tvars xi of |
52 (case AList.lookup (op =) tvars xi of |
55 SOME S => S |
53 SOME S => S |
56 | NONE => error_var "No such type variable in theorem: " (xi, pos)); |
54 | NONE => error_var "No such type variable in theorem: " (xi, pos)); |
57 |
55 |
58 fun the_type vars (xi, pos) : typ = |
56 fun the_type vars (xi, pos) : typ = |
59 (case AList.lookup (op =) vars xi of |
57 (case AList.lookup (op =) vars xi of |
60 SOME T => T |
58 SOME T => T |
61 | NONE => error_var "No such variable in theorem: " (xi, pos)); |
59 | NONE => error_var "No such variable in theorem: " (xi, pos)); |
62 |
60 |
|
61 local |
|
62 |
63 fun instantiate inst = |
63 fun instantiate inst = |
64 Term_Subst.instantiate ([], map (fn (xi, t) => ((xi, Term.fastype_of t), t)) inst) #> |
64 Term_Subst.instantiate ([], map (fn (xi, t) => ((xi, Term.fastype_of t), t)) inst) #> |
65 Envir.beta_norm; |
65 Envir.beta_norm; |
66 |
66 |
67 fun make_instT f v = |
67 fun make_instT f v = |
75 val t = Var v; |
75 val t = Var v; |
76 val t' = f t; |
76 val t' = f t; |
77 in if t aconv t' then NONE else SOME (t, t') end; |
77 in if t aconv t' then NONE else SOME (t, t') end; |
78 |
78 |
79 in |
79 in |
|
80 |
|
81 fun readT ctxt tvars ((xi, pos), s) = |
|
82 let |
|
83 val S = the_sort tvars (xi, pos); |
|
84 val T = Syntax.read_typ ctxt s; |
|
85 in |
|
86 if Sign.of_sort (Proof_Context.theory_of ctxt) (T, S) then ((xi, S), T) |
|
87 else error_var "Incompatible sort for typ instantiation of " (xi, pos) |
|
88 end; |
80 |
89 |
81 fun read_termTs ctxt ss Ts = |
90 fun read_termTs ctxt ss Ts = |
82 let |
91 let |
83 fun parse T = if T = propT then Syntax.parse_prop ctxt else Syntax.parse_term ctxt; |
92 fun parse T = if T = propT then Syntax.parse_prop ctxt else Syntax.parse_term ctxt; |
84 val ts = map2 parse Ts ss; |
93 val ts = map2 parse Ts ss; |
86 map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts |
95 map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts |
87 |> Syntax.check_terms ctxt |
96 |> Syntax.check_terms ctxt |
88 |> Variable.polymorphic ctxt; |
97 |> Variable.polymorphic ctxt; |
89 val Ts' = map Term.fastype_of ts'; |
98 val Ts' = map Term.fastype_of ts'; |
90 val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty; |
99 val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty; |
91 in (ts', map (apsnd snd) (Vartab.dest tyenv)) end; |
100 val tyenv' = Vartab.fold (fn (xi, (S, T)) => cons ((xi, S), T)) tyenv []; |
92 |
101 in (ts', tyenv') end; |
93 fun read_insts ctxt mixed_insts (tvars, vars) = |
102 |
94 let |
103 fun read_insts ctxt (tvars, vars) mixed_insts = |
95 val thy = Proof_Context.theory_of ctxt; |
104 let |
96 |
|
97 val (type_insts, term_insts) = partition_insts mixed_insts; |
105 val (type_insts, term_insts) = partition_insts mixed_insts; |
98 |
106 |
99 |
107 |
100 (* type instantiations *) |
108 (* type instantiations *) |
101 |
109 |
102 fun readT ((xi, pos), s) = |
110 val instT1 = Term_Subst.instantiateT (map (readT ctxt tvars) type_insts); |
103 let |
|
104 val S = the_sort tvars (xi, pos); |
|
105 val T = Syntax.read_typ ctxt s; |
|
106 in |
|
107 if Sign.of_sort thy (T, S) then ((xi, S), T) |
|
108 else error_var "Incompatible sort for typ instantiation of " (xi, pos) |
|
109 end; |
|
110 |
|
111 val instT1 = Term_Subst.instantiateT (map readT type_insts); |
|
112 val vars1 = map (apsnd instT1) vars; |
111 val vars1 = map (apsnd instT1) vars; |
113 |
112 |
114 |
113 |
115 (* term instantiations *) |
114 (* term instantiations *) |
116 |
115 |
117 val (xs, ss) = split_list term_insts; |
116 val (xs, ss) = split_list term_insts; |
118 val Ts = map (the_type vars1) xs; |
117 val Ts = map (the_type vars1) xs; |
119 val (ts, inferred) = read_termTs ctxt ss Ts; |
118 val (ts, inferred) = read_termTs ctxt ss Ts; |
120 |
119 |
121 val instT2 = Term.typ_subst_TVars inferred; |
120 val instT2 = Term_Subst.instantiateT inferred; |
122 val vars2 = map (apsnd instT2) vars1; |
121 val vars2 = map (apsnd instT2) vars1; |
123 val inst2 = instantiate (map #1 xs ~~ ts); |
122 val inst2 = instantiate (map #1 xs ~~ ts); |
124 |
123 |
125 |
124 |
126 (* result *) |
125 (* result *) |
137 val ctxt' = ctxt |
136 val ctxt' = ctxt |
138 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2 |
137 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2 |
139 |> Variable.declare_thm thm; |
138 |> Variable.declare_thm thm; |
140 val tvars = Thm.fold_terms Term.add_tvars thm []; |
139 val tvars = Thm.fold_terms Term.add_tvars thm []; |
141 val vars = Thm.fold_terms Term.add_vars thm []; |
140 val vars = Thm.fold_terms Term.add_vars thm []; |
142 val insts = read_insts ctxt' mixed_insts (tvars, vars); |
141 val insts = read_insts ctxt' (tvars, vars) mixed_insts; |
143 in |
142 in |
144 Drule.instantiate_normalize insts thm |
143 Drule.instantiate_normalize insts thm |
145 |> singleton (Proof_Context.export ctxt' ctxt) |
144 |> singleton (Proof_Context.export ctxt' ctxt) |
146 |> Rule_Cases.save thm |
145 |> Rule_Cases.save thm |
147 end; |
146 end; |
210 |
209 |
211 (* resolution after lifting and instantiation; may refer to parameters of the subgoal *) |
210 (* resolution after lifting and instantiation; may refer to parameters of the subgoal *) |
212 |
211 |
213 fun bires_inst_tac bires_flag ctxt mixed_insts thm i st = CSUBGOAL (fn (cgoal, _) => |
212 fun bires_inst_tac bires_flag ctxt mixed_insts thm i st = CSUBGOAL (fn (cgoal, _) => |
214 let |
213 let |
215 val thy = Proof_Context.theory_of ctxt; |
|
216 |
|
217 val (Tinsts, tinsts) = partition_insts mixed_insts; |
214 val (Tinsts, tinsts) = partition_insts mixed_insts; |
|
215 |
|
216 |
|
217 (* goal context *) |
|
218 |
218 val goal = Thm.term_of cgoal; |
219 val goal = Thm.term_of cgoal; |
219 |
|
220 val params = |
220 val params = |
221 Logic.strip_params goal |
221 Logic.strip_params goal |
222 (*as they are printed: bound variables with the same name are renamed*) |
222 (*as they are printed: bound variables with the same name are renamed*) |
223 |> Term.rename_wrt_term goal |
223 |> Term.rename_wrt_term goal |
224 |> rev; |
224 |> rev; |
226 |> Variable.declare_thm thm |
226 |> Variable.declare_thm thm |
227 |> Thm.fold_terms Variable.declare_constraints st |
227 |> Thm.fold_terms Variable.declare_constraints st |
228 |> Proof_Context.add_fixes (map (fn (x, T) => (Binding.name x, SOME T, NoSyn)) params); |
228 |> Proof_Context.add_fixes (map (fn (x, T) => (Binding.name x, SOME T, NoSyn)) params); |
229 |
229 |
230 |
230 |
231 (* process type insts: Tinsts_env *) |
231 (* preprocess rule *) |
232 |
232 |
233 val (rtypes, rsorts) = Drule.types_sorts thm; |
233 val tvars = Thm.fold_terms Term.add_tvars thm []; |
234 fun readT ((xi, pos), s) = |
234 val vars = Thm.fold_terms Term.add_vars thm []; |
235 let |
235 |
236 val S = |
236 val Tinsts_env = map (readT ctxt' tvars) Tinsts; |
237 (case rsorts xi of |
|
238 SOME S => S |
|
239 | NONE => error_var "No such type variable in theorem: " (xi, pos)); |
|
240 val T = Syntax.read_typ ctxt' s; |
|
241 val U = TVar (xi, S); |
|
242 in |
|
243 if Sign.typ_instance thy (T, U) then (U, T) |
|
244 else error_var "Cannot instantiate: " (xi, pos) |
|
245 end; |
|
246 val Tinsts_env = map readT Tinsts; |
|
247 |
|
248 |
|
249 (* preprocess rule: extract vars and their types, apply Tinsts *) |
|
250 |
|
251 fun get_typ (xi, pos) = |
|
252 (case rtypes xi of |
|
253 SOME T => typ_subst_atomic Tinsts_env T |
|
254 | NONE => error_var "No such variable in theorem: " (xi, pos) xi); |
|
255 val (xis, ss) = split_list tinsts; |
237 val (xis, ss) = split_list tinsts; |
256 val Ts = map get_typ xis; |
238 val Ts = map (Term_Subst.instantiateT Tinsts_env o the_type vars) xis; |
257 |
239 |
258 val (ts, envT) = |
240 val (ts, envT) = |
259 read_termTs (Proof_Context.set_mode Proof_Context.mode_schematic ctxt') ss Ts; |
241 read_termTs (Proof_Context.set_mode Proof_Context.mode_schematic ctxt') ss Ts; |
260 val envT' = |
242 val envT' = map (fn (v, T) => (TVar v, T)) (envT @ Tinsts_env); |
261 map (fn (xi, T) => (TVar (xi, the (rsorts xi)), T)) envT @ Tinsts_env; |
|
262 val cenv = |
243 val cenv = |
263 map (fn ((xi, _), t) => apply2 (Thm.cterm_of ctxt') (Var (xi, fastype_of t), t)) |
244 map (fn ((xi, _), t) => apply2 (Thm.cterm_of ctxt') (Var (xi, fastype_of t), t)) |
264 (distinct |
245 (distinct |
265 (fn ((x1, t1), (x2, t2)) => x1 = x2 andalso t1 aconv t2) |
246 (fn ((x1, t1), (x2, t2)) => x1 = x2 andalso t1 aconv t2) |
266 (xis ~~ ts)); |
247 (xis ~~ ts)); |