src/HOL/Tools/Sledgehammer/sledgehammer_fact.ML
changeset 59582 0fbed69ff081
parent 59433 9da5b2c61049
child 59755 f8d164ab0dc1
equal deleted inserted replaced
59580:cbc38731d42f 59582:0fbed69ff081
    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)
   493           in
   493           in
   494             snd (fold_rev (fn th => fn (j, accum) =>
   494             snd (fold_rev (fn th => fn (j, accum) =>
   495               (j - 1,
   495               (j - 1,
   496                if not (member Thm.eq_thm_prop add_ths th) andalso
   496                if not (member Thm.eq_thm_prop add_ths th) andalso
   497                   (is_likely_tautology_too_meta_or_too_technical th orelse
   497                   (is_likely_tautology_too_meta_or_too_technical th orelse
   498                    is_too_complex (prop_of th)) then
   498                    is_too_complex (Thm.prop_of th)) then
   499                  accum
   499                  accum
   500                else
   500                else
   501                  let
   501                  let
   502                    fun get_name () =
   502                    fun get_name () =
   503                      if name0 = "" then
   503                      if name0 = "" then