164 SOME (p_name, ind_T) |
164 SOME (p_name, ind_T) |
165 else |
165 else |
166 NONE |
166 NONE |
167 | _ => NONE |
167 | _ => NONE |
168 |
168 |
169 fun instantiate_induct_rule ctxt concl_prop p_name ((name, _), (multi, th)) |
169 fun instantiate_induct_rule ctxt concl_prop p_name ((name, loc), (multi, th)) |
170 ind_x = |
170 ind_x = |
171 let |
171 let |
172 fun varify_noninducts (t as Free (s, T)) = |
172 fun varify_noninducts (t as Free (s, T)) = |
173 if (s, T) = ind_x orelse can dest_funT T then t else Var ((s, 0), T) |
173 if (s, T) = ind_x orelse can dest_funT T then t else Var ((s, 0), T) |
174 | varify_noninducts t = t |
174 | varify_noninducts t = t |
175 val p_inst = |
175 val p_inst = |
176 concl_prop |> map_aterms varify_noninducts |> close_form |
176 concl_prop |> map_aterms varify_noninducts |> close_form |
177 |> lambda (Free ind_x) |
177 |> lambda (Free ind_x) |
178 |> string_for_term ctxt |
178 |> string_for_term ctxt |
179 in |
179 in |
180 ((fn () => name () ^ "[where " ^ p_name ^ " = " ^ quote p_inst ^ "]", |
180 ((fn () => name () ^ "[where " ^ p_name ^ " = " ^ quote p_inst ^ "]", loc), |
181 Local), |
|
182 (multi, th |> read_instantiate ctxt [((p_name, 0), p_inst)])) |
181 (multi, th |> read_instantiate ctxt [((p_name, 0), p_inst)])) |
183 end |
182 end |
184 |
183 |
185 fun type_match thy (T1, T2) = |
184 fun type_match thy (T1, T2) = |
186 (Sign.typ_match thy (T2, T1) Vartab.empty; true) |
185 (Sign.typ_match thy (T2, T1) Vartab.empty; true) |
259 |
258 |
260 fun is_formula_type T = (T = HOLogic.boolT orelse T = propT) |
259 fun is_formula_type T = (T = HOLogic.boolT orelse T = propT) |
261 |
260 |
262 fun pconsts_in_terms thy is_built_in_const also_skolems pos ts = |
261 fun pconsts_in_terms thy is_built_in_const also_skolems pos ts = |
263 let |
262 let |
264 (* Giving a penalty to Skolems is a good idea, but that penalty shouldn't |
|
265 increase linearly with the number of Skolems in the fact. Hence, we |
|
266 create equivalence classes of Skolems by reusing fresh Skolem names. *) |
|
267 val skolem_cache = Unsynchronized.ref "" |
|
268 fun get_skolem_name () = |
|
269 (if !skolem_cache = "" then skolem_cache := gensym skolem_prefix else (); |
|
270 !skolem_cache) |
|
271 val flip = Option.map not |
263 val flip = Option.map not |
272 (* We include free variables, as well as constants, to handle locales. For |
264 (* We include free variables, as well as constants, to handle locales. For |
273 each quantifiers that must necessarily be skolemized by the automatic |
265 each quantifiers that must necessarily be skolemized by the automatic |
274 prover, we introduce a fresh constant to simulate the effect of |
266 prover, we introduce a fresh constant to simulate the effect of |
275 Skolemization. *) |
267 Skolemization. *) |
288 | (_, ts) => fold do_term ts |
280 | (_, ts) => fold do_term ts |
289 fun do_quantifier will_surely_be_skolemized abs_T body_t = |
281 fun do_quantifier will_surely_be_skolemized abs_T body_t = |
290 do_formula pos body_t |
282 do_formula pos body_t |
291 #> (if also_skolems andalso will_surely_be_skolemized then |
283 #> (if also_skolems andalso will_surely_be_skolemized then |
292 add_pconst_to_table true |
284 add_pconst_to_table true |
293 (get_skolem_name (), PType (order_of_type abs_T, [])) |
285 (gensym skolem_prefix, PType (order_of_type abs_T, [])) |
294 else |
286 else |
295 I) |
287 I) |
296 and do_term_or_formula T = |
288 and do_term_or_formula T = |
297 if is_formula_type T then do_formula NONE else do_term |
289 if is_formula_type T then do_formula NONE else do_term |
298 and do_formula pos t = |
290 and do_formula pos t = |