66 in |
66 in |
67 if Sign.of_sort (Proof_Context.theory_of ctxt) (T, S) then ((xi, S), T) |
67 if Sign.of_sort (Proof_Context.theory_of ctxt) (T, S) then ((xi, S), T) |
68 else error_var "Bad sort for instantiation of type variable: " (xi, pos) |
68 else error_var "Bad sort for instantiation of type variable: " (xi, pos) |
69 end; |
69 end; |
70 |
70 |
71 fun read_terms ctxt ss Ts = |
71 fun read_terms ss Ts ctxt = |
72 let |
72 let |
73 fun parse T = if T = propT then Syntax.parse_prop ctxt else Syntax.parse_term ctxt; |
73 fun parse T = if T = propT then Syntax.parse_prop ctxt else Syntax.parse_term ctxt; |
74 val ts = map2 parse Ts ss; |
74 val (ts, ctxt') = fold_map Variable.fix_dummy_patterns (map2 parse Ts ss) ctxt; |
75 val ts' = |
75 val ts' = |
76 map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts |
76 map2 (Type.constraint o Type_Infer.paramify_vars) Ts ts |
77 |> Syntax.check_terms ctxt |
77 |> Syntax.check_terms ctxt' |
78 |> Variable.polymorphic ctxt; |
78 |> Variable.polymorphic ctxt'; |
79 val Ts' = map Term.fastype_of ts'; |
79 val Ts' = map Term.fastype_of ts'; |
80 val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty; |
80 val tyenv = fold Type.raw_match (Ts ~~ Ts') Vartab.empty; |
81 val tyenv' = Vartab.fold (fn (xi, (S, T)) => cons ((xi, S), T)) tyenv []; |
81 val tyenv' = Vartab.fold (fn (xi, (S, T)) => cons ((xi, S), T)) tyenv []; |
82 in (ts', tyenv') end; |
82 in ((ts', tyenv'), ctxt') end; |
83 |
83 |
84 fun make_instT f v = |
84 fun make_instT f v = |
85 let |
85 let |
86 val T = TVar v; |
86 val T = TVar v; |
87 val T' = f T; |
87 val T' = f T; |
93 val t' = f t; |
93 val t' = f t; |
94 in if t aconv t' then NONE else SOME (v, t') end; |
94 in if t aconv t' then NONE else SOME (v, t') end; |
95 |
95 |
96 in |
96 in |
97 |
97 |
98 fun read_insts ctxt mixed_insts thm = |
98 fun read_insts thm mixed_insts ctxt = |
99 let |
99 let |
100 val (type_insts, term_insts) = |
100 val (type_insts, term_insts) = |
101 List.partition (fn (((x, _), _), _) => String.isPrefix "'" x) mixed_insts; |
101 List.partition (fn (((x, _), _), _) => String.isPrefix "'" x) mixed_insts; |
102 |
102 |
103 val tvars = Thm.fold_terms Term.add_tvars thm []; |
103 val tvars = Thm.fold_terms Term.add_tvars thm []; |
108 val vars1 = map (apsnd instT1) vars; |
108 val vars1 = map (apsnd instT1) vars; |
109 |
109 |
110 (*term instantiations*) |
110 (*term instantiations*) |
111 val (xs, ss) = split_list term_insts; |
111 val (xs, ss) = split_list term_insts; |
112 val Ts = map (the_type vars1) xs; |
112 val Ts = map (the_type vars1) xs; |
113 val (ts, inferred) = read_terms ctxt ss Ts; |
113 val ((ts, inferred), ctxt') = read_terms ss Ts ctxt; |
114 |
114 |
115 (*implicit type instantiations*) |
115 (*implicit type instantiations*) |
116 val instT2 = Term_Subst.instantiateT inferred; |
116 val instT2 = Term_Subst.instantiateT inferred; |
117 val vars2 = map (apsnd instT2) vars1; |
117 val vars2 = map (apsnd instT2) vars1; |
118 val inst2 = |
118 val inst2 = |
119 Term_Subst.instantiate ([], map2 (fn (xi, _) => fn t => ((xi, Term.fastype_of t), t)) xs ts) |
119 Term_Subst.instantiate ([], map2 (fn (xi, _) => fn t => ((xi, Term.fastype_of t), t)) xs ts) |
120 #> Envir.beta_norm; |
120 #> Envir.beta_norm; |
121 |
121 |
122 val inst_tvars = map_filter (make_instT (instT2 o instT1)) tvars; |
122 val inst_tvars = map_filter (make_instT (instT2 o instT1)) tvars; |
123 val inst_vars = map_filter (make_inst inst2) vars2; |
123 val inst_vars = map_filter (make_inst inst2) vars2; |
124 in (inst_tvars, inst_vars) end; |
124 in ((inst_tvars, inst_vars), ctxt') end; |
125 |
125 |
126 end; |
126 end; |
127 |
127 |
128 |
128 |
129 |
129 |
132 fun where_rule ctxt mixed_insts fixes thm = |
132 fun where_rule ctxt mixed_insts fixes thm = |
133 let |
133 let |
134 val ctxt' = ctxt |
134 val ctxt' = ctxt |
135 |> Variable.declare_thm thm |
135 |> Variable.declare_thm thm |
136 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2; |
136 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes |> #2; |
137 val (inst_tvars, inst_vars) = read_insts ctxt' mixed_insts thm; |
137 val ((inst_tvars, inst_vars), ctxt'') = read_insts thm mixed_insts ctxt'; |
138 in |
138 in |
139 thm |
139 thm |
140 |> Drule.instantiate_normalize |
140 |> Drule.instantiate_normalize |
141 (map (apply2 (Thm.ctyp_of ctxt) o apfst TVar) inst_tvars, |
141 (map (apply2 (Thm.ctyp_of ctxt'') o apfst TVar) inst_tvars, |
142 map (apply2 (Thm.cterm_of ctxt) o apfst Var) inst_vars) |
142 map (apply2 (Thm.cterm_of ctxt'') o apfst Var) inst_vars) |
143 |> singleton (Variable.export ctxt' ctxt) |
143 |> singleton (Variable.export ctxt'' ctxt) |
144 |> Rule_Cases.save thm |
144 |> Rule_Cases.save thm |
145 end; |
145 end; |
146 |
146 |
147 fun of_rule ctxt (args, concl_args) fixes thm = |
147 fun of_rule ctxt (args, concl_args) fixes thm = |
148 let |
148 let |
223 (* local fixes *) |
223 (* local fixes *) |
224 |
224 |
225 val (fixed, fixes_ctxt) = param_ctxt |
225 val (fixed, fixes_ctxt) = param_ctxt |
226 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes; |
226 |> Proof_Context.read_vars fixes |-> Proof_Context.add_fixes; |
227 |
227 |
228 val (inst_tvars, inst_vars) = read_insts fixes_ctxt mixed_insts thm; |
228 val ((inst_tvars, inst_vars), inst_ctxt) = read_insts thm mixed_insts fixes_ctxt; |
229 |
229 |
230 |
230 |
231 (* lift and instantiate rule *) |
231 (* lift and instantiate rule *) |
232 |
232 |
233 val inc = Thm.maxidx_of st + 1; |
233 val inc = Thm.maxidx_of st + 1; |
236 fun lift_term t = |
236 fun lift_term t = |
237 fold_rev Term.absfree (param_names ~~ paramTs) |
237 fold_rev Term.absfree (param_names ~~ paramTs) |
238 (Logic.incr_indexes (fixed, paramTs, inc) t); |
238 (Logic.incr_indexes (fixed, paramTs, inc) t); |
239 |
239 |
240 val inst_tvars' = inst_tvars |
240 val inst_tvars' = inst_tvars |
241 |> map (apply2 (Thm.ctyp_of fixes_ctxt o Logic.incr_tvar inc) o apfst TVar); |
241 |> map (apply2 (Thm.ctyp_of inst_ctxt o Logic.incr_tvar inc) o apfst TVar); |
242 val inst_vars' = inst_vars |
242 val inst_vars' = inst_vars |
243 |> map (fn (v, t) => apply2 (Thm.cterm_of fixes_ctxt) (lift_var v, lift_term t)); |
243 |> map (fn (v, t) => apply2 (Thm.cterm_of inst_ctxt) (lift_var v, lift_term t)); |
244 |
244 |
245 val thm' = |
245 val thm' = |
246 Drule.instantiate_normalize (inst_tvars', inst_vars') |
246 Drule.instantiate_normalize (inst_tvars', inst_vars') |
247 (Thm.lift_rule cgoal thm) |
247 (Thm.lift_rule cgoal thm) |
248 |> singleton (Variable.export fixes_ctxt param_ctxt); |
248 |> singleton (Variable.export inst_ctxt param_ctxt); |
249 in |
249 in |
250 compose_tac param_ctxt (bires_flag, thm', Thm.nprems_of thm) i |
250 compose_tac param_ctxt (bires_flag, thm', Thm.nprems_of thm) i |
251 end) i st; |
251 end) i st; |
252 |
252 |
253 val res_inst_tac = bires_inst_tac false; |
253 val res_inst_tac = bires_inst_tac false; |