89 | is_rec_def (@{const Pure.imp} $ _ $ t2) = is_rec_def t2 |
89 | is_rec_def (@{const Pure.imp} $ _ $ t2) = is_rec_def t2 |
90 | is_rec_def (Const (@{const_name Pure.eq}, _) $ t1 $ t2) = is_rec_eq t1 t2 |
90 | is_rec_def (Const (@{const_name Pure.eq}, _) $ t1 $ t2) = is_rec_eq t1 t2 |
91 | is_rec_def (Const (@{const_name HOL.eq}, _) $ t1 $ t2) = is_rec_eq t1 t2 |
91 | is_rec_def (Const (@{const_name HOL.eq}, _) $ t1 $ t2) = is_rec_eq t1 t2 |
92 | is_rec_def _ = false |
92 | is_rec_def _ = false |
93 |
93 |
94 fun is_assum assms th = exists (fn ct => prop_of th aconv term_of ct) assms |
94 fun is_assum assms th = exists (fn ct => Thm.prop_of th aconv Thm.term_of ct) assms |
95 fun is_chained chained = member Thm.eq_thm_prop chained |
95 fun is_chained chained = member Thm.eq_thm_prop chained |
96 |
96 |
97 fun scope_of_thm global assms chained th = |
97 fun scope_of_thm global assms chained th = |
98 if is_chained chained th then Chained |
98 if is_chained chained th then Chained |
99 else if global then Global |
99 else if global then Global |
129 |
129 |
130 fun status_of_thm css name th = |
130 fun status_of_thm css name th = |
131 if Termtab.is_empty css then |
131 if Termtab.is_empty css then |
132 General |
132 General |
133 else |
133 else |
134 let val t = prop_of th in |
134 let val t = Thm.prop_of th in |
135 (* FIXME: use structured name *) |
135 (* FIXME: use structured name *) |
136 if String.isSubstring ".induct" name andalso may_be_induction t then |
136 if String.isSubstring ".induct" name andalso may_be_induction t then |
137 Induction |
137 Induction |
138 else |
138 else |
139 let val t = normalize_vars t in |
139 let val t = normalize_vars t in |
222 |
222 |
223 val sep_that = Long_Name.separator ^ Obtain.thatN |
223 val sep_that = Long_Name.separator ^ Obtain.thatN |
224 val skolem_thesis = Name.skolem Auto_Bind.thesisN |
224 val skolem_thesis = Name.skolem Auto_Bind.thesisN |
225 |
225 |
226 fun is_that_fact th = |
226 fun is_that_fact th = |
227 exists_subterm (fn Free (s, _) => s = skolem_thesis | _ => false) (prop_of th) |
227 exists_subterm (fn Free (s, _) => s = skolem_thesis | _ => false) (Thm.prop_of th) |
228 andalso String.isSuffix sep_that (Thm.get_name_hint th) |
228 andalso String.isSuffix sep_that (Thm.get_name_hint th) |
229 |
229 |
230 datatype interest = Deal_Breaker | Interesting | Boring |
230 datatype interest = Deal_Breaker | Interesting | Boring |
231 |
231 |
232 fun combine_interests Deal_Breaker _ = Deal_Breaker |
232 fun combine_interests Deal_Breaker _ = Deal_Breaker |
264 interest_of_prop Ts (t $ eta_expand Ts u 1) |
264 interest_of_prop Ts (t $ eta_expand Ts u 1) |
265 | interest_of_prop _ (Const (@{const_name Pure.eq}, _) $ t $ u) = |
265 | interest_of_prop _ (Const (@{const_name Pure.eq}, _) $ t $ u) = |
266 combine_interests (interest_of_bool t) (interest_of_bool u) |
266 combine_interests (interest_of_bool t) (interest_of_bool u) |
267 | interest_of_prop _ _ = Deal_Breaker |
267 | interest_of_prop _ _ = Deal_Breaker |
268 |
268 |
269 val t = prop_of th |
269 val t = Thm.prop_of th |
270 in |
270 in |
271 (interest_of_prop [] t <> Interesting andalso not (Thm.eq_thm_prop (@{thm ext}, th))) orelse |
271 (interest_of_prop [] t <> Interesting andalso not (Thm.eq_thm_prop (@{thm ext}, th))) orelse |
272 is_that_fact th |
272 is_that_fact th |
273 end |
273 end |
274 |
274 |
296 end) |
296 end) |
297 (Term.add_vars t [] |> sort_wrt (fst o fst)) |
297 (Term.add_vars t [] |> sort_wrt (fst o fst)) |
298 |> fst |
298 |> fst |
299 |
299 |
300 fun backquote_term ctxt = close_form #> hackish_string_of_term ctxt #> backquote |
300 fun backquote_term ctxt = close_form #> hackish_string_of_term ctxt #> backquote |
301 fun backquote_thm ctxt = backquote_term ctxt o prop_of |
301 fun backquote_thm ctxt = backquote_term ctxt o Thm.prop_of |
302 |
302 |
303 (* TODO: rewrite to use nets and/or to reuse existing data structures *) |
303 (* TODO: rewrite to use nets and/or to reuse existing data structures *) |
304 fun clasimpset_rule_table_of ctxt = |
304 fun clasimpset_rule_table_of ctxt = |
305 let val simps = ctxt |> simpset_of |> dest_ss |> #simps in |
305 let val simps = ctxt |> simpset_of |> dest_ss |> #simps in |
306 if length simps >= max_simps_for_clasimpset then |
306 if length simps >= max_simps_for_clasimpset then |
307 Termtab.empty |
307 Termtab.empty |
308 else |
308 else |
309 let |
309 let |
310 fun add stature th = Termtab.update (normalize_vars (prop_of th), stature) |
310 fun add stature th = Termtab.update (normalize_vars (Thm.prop_of th), stature) |
311 |
311 |
312 val {safeIs, (* safeEs, *) hazIs, (* hazEs, *) ...} = ctxt |> claset_of |> Classical.rep_cs |
312 val {safeIs, (* safeEs, *) hazIs, (* hazEs, *) ...} = ctxt |> claset_of |> Classical.rep_cs |
313 val intros = Item_Net.content safeIs @ Item_Net.content hazIs |
313 val intros = Item_Net.content safeIs @ Item_Net.content hazIs |
314 (* Add once it is used: |
314 (* Add once it is used: |
315 val elims = Item_Net.content safeEs @ Item_Net.content hazEs |
315 val elims = Item_Net.content safeEs @ Item_Net.content hazEs |
318 val specs = Spec_Rules.get ctxt |
318 val specs = Spec_Rules.get ctxt |
319 val (rec_defs, nonrec_defs) = specs |
319 val (rec_defs, nonrec_defs) = specs |
320 |> filter (curry (op =) Spec_Rules.Equational o fst) |
320 |> filter (curry (op =) Spec_Rules.Equational o fst) |
321 |> maps (snd o snd) |
321 |> maps (snd o snd) |
322 |> filter_out (member Thm.eq_thm_prop risky_defs) |
322 |> filter_out (member Thm.eq_thm_prop risky_defs) |
323 |> List.partition (is_rec_def o prop_of) |
323 |> List.partition (is_rec_def o Thm.prop_of) |
324 val spec_intros = specs |
324 val spec_intros = specs |
325 |> filter (member (op =) [Spec_Rules.Inductive, Spec_Rules.Co_Inductive] o fst) |
325 |> filter (member (op =) [Spec_Rules.Inductive, Spec_Rules.Co_Inductive] o fst) |
326 |> maps (snd o snd) |
326 |> maps (snd o snd) |
327 in |
327 in |
328 Termtab.empty |
328 Termtab.empty |
357 SOME (pref, suf) => [s, pref ^ suf] |
357 SOME (pref, suf) => [s, pref ^ suf] |
358 | NONE => [s]) |
358 | NONE => [s]) |
359 |
359 |
360 fun build_name_tables name_of facts = |
360 fun build_name_tables name_of facts = |
361 let |
361 let |
362 fun cons_thm (_, th) = Termtab.cons_list (normalize_vars (normalize_eq (prop_of th)), th) |
362 fun cons_thm (_, th) = Termtab.cons_list (normalize_vars (normalize_eq (Thm.prop_of th)), th) |
363 fun add_plain canon alias = |
363 fun add_plain canon alias = |
364 Symtab.update (Thm.get_name_hint alias, name_of (if_thm_before canon alias)) |
364 Symtab.update (Thm.get_name_hint alias, name_of (if_thm_before canon alias)) |
365 fun add_plains (_, aliases as canon :: _) = fold (add_plain canon) aliases |
365 fun add_plains (_, aliases as canon :: _) = fold (add_plain canon) aliases |
366 fun add_inclass (name, target) = fold (fn s => Symtab.update (s, target)) (un_class_ify name) |
366 fun add_inclass (name, target) = fold (fn s => Symtab.update (s, target)) (un_class_ify name) |
367 val prop_tab = fold cons_thm facts Termtab.empty |
367 val prop_tab = fold cons_thm facts Termtab.empty |
371 (plain_name_tab, inclass_name_tab) |
371 (plain_name_tab, inclass_name_tab) |
372 end |
372 end |
373 |
373 |
374 fun fact_distinct eq facts = |
374 fun fact_distinct eq facts = |
375 fold (fn fact as (_, th) => |
375 fold (fn fact as (_, th) => |
376 Net.insert_term_safe (eq o apply2 (normalize_eq o prop_of o snd)) |
376 Net.insert_term_safe (eq o apply2 (normalize_eq o Thm.prop_of o snd)) |
377 (normalize_eq (prop_of th), fact)) |
377 (normalize_eq (Thm.prop_of th), fact)) |
378 facts Net.empty |
378 facts Net.empty |
379 |> Net.entries |
379 |> Net.entries |
380 |
380 |
381 fun struct_induct_rule_on th = |
381 fun struct_induct_rule_on th = |
382 (case Logic.strip_horn (prop_of th) of |
382 (case Logic.strip_horn (Thm.prop_of th) of |
383 (prems, @{const Trueprop} $ ((p as Var ((p_name, 0), _)) $ (a as Var (_, ind_T)))) => |
383 (prems, @{const Trueprop} $ ((p as Var ((p_name, 0), _)) $ (a as Var (_, ind_T)))) => |
384 if not (is_TVar ind_T) andalso length prems > 1 andalso |
384 if not (is_TVar ind_T) andalso length prems > 1 andalso |
385 exists (exists_subterm (curry (op aconv) p)) prems andalso |
385 exists (exists_subterm (curry (op aconv) p)) prems andalso |
386 not (exists (exists_subterm (curry (op aconv) a)) prems) then |
386 not (exists (exists_subterm (curry (op aconv) a)) prems) then |
387 SOME (p_name, ind_T) |
387 SOME (p_name, ind_T) |