src/HOL/Tools/Sledgehammer/sledgehammer_filter.ML
changeset 42641 2cd4e6463842
parent 42638 a7a30721767a
child 42646 4781fcd53572
equal deleted inserted replaced
42640:879d2d6b05ce 42641:2cd4e6463842
    39   val is_global_locality : locality -> bool
    39   val is_global_locality : locality -> bool
    40   val fact_from_ref :
    40   val fact_from_ref :
    41     Proof.context -> unit Symtab.table -> thm list
    41     Proof.context -> unit Symtab.table -> thm list
    42     -> Facts.ref * Attrib.src list -> ((string * locality) * thm) list
    42     -> Facts.ref * Attrib.src list -> ((string * locality) * thm) list
    43   val all_facts :
    43   val all_facts :
    44     Proof.context -> 'a Symtab.table -> bool -> relevance_fudge -> thm list
    44     Proof.context -> 'a Symtab.table -> bool -> thm list -> thm list
    45     -> thm list -> (((unit -> string) * locality) * (bool * thm)) list
    45     -> (((unit -> string) * locality) * (bool * thm)) list
    46   val const_names_in_fact :
    46   val const_names_in_fact :
    47     theory -> (string * typ -> term list -> bool * term list) -> term
    47     theory -> (string * typ -> term list -> bool * term list) -> term
    48     -> string list
    48     -> string list
    49   val is_dangerous_term : term -> bool
    49   val is_dangerous_term : term -> bool
    50   val relevant_facts :
    50   val relevant_facts :
   657   let val names = Long_Name.explode a in
   657   let val names = Long_Name.explode a in
   658     (length names > 2 andalso not (hd names = "local") andalso
   658     (length names > 2 andalso not (hd names = "local") andalso
   659      String.isSuffix "_def" a) orelse String.isSuffix "_defs" a
   659      String.isSuffix "_def" a) orelse String.isSuffix "_defs" a
   660   end
   660   end
   661 
   661 
   662 fun mk_fact_table f xs =
   662 fun mk_fact_table g f xs =
   663   fold (Termtab.update o `(prop_of o f)) xs Termtab.empty
   663   fold (Termtab.update o `(g o prop_of o f)) xs Termtab.empty
   664 fun uniquify xs = Termtab.fold (cons o snd) (mk_fact_table snd xs) []
   664 fun uniquify xs = Termtab.fold (cons o snd) (mk_fact_table I snd xs) []
   665 
   665 
   666 (* FIXME: put other record thms here, or declare as "no_atp" *)
   666 (* FIXME: put other record thms here, or declare as "no_atp" *)
   667 val multi_base_blacklist =
   667 val multi_base_blacklist =
   668   ["defs", "select_defs", "update_defs", "split", "splits", "split_asm",
   668   ["defs", "select_defs", "update_defs", "split", "splits", "split_asm",
   669    "cases", "ext_cases", "eq.simps", "eq.refl", "nchotomy", "case_cong",
   669    "cases", "ext_cases", "eq.simps", "eq.refl", "nchotomy", "case_cong",
   787     is_formula_too_complex t orelse exists_type type_has_top_sort t orelse
   787     is_formula_too_complex t orelse exists_type type_has_top_sort t orelse
   788     exists_sledgehammer_const t orelse exists_low_level_class_const t orelse
   788     exists_sledgehammer_const t orelse exists_low_level_class_const t orelse
   789     is_metastrange_theorem thm orelse is_that_fact thm
   789     is_metastrange_theorem thm orelse is_that_fact thm
   790   end
   790   end
   791 
   791 
       
   792 fun meta_equify (@{const Trueprop}
       
   793                  $ (Const (@{const_name HOL.eq}, Type (_, [T, _])) $ t1 $ t2)) =
       
   794     Const (@{const_name "=="}, T --> T --> @{typ prop}) $ t1 $ t2
       
   795   | meta_equify t = t
       
   796 
       
   797 val normalize_simp_prop =
       
   798   meta_equify
       
   799   #> map_aterms (fn Var ((s, _), T) => Var ((s, 0), T) | t => t)
       
   800   #> map_types (map_type_tvar (fn ((s, _), S) => TVar ((s, 0), S)))
       
   801 
   792 fun clasimpset_rules_of ctxt =
   802 fun clasimpset_rules_of ctxt =
   793   let
   803   let
   794     val {safeIs, safeEs, hazIs, hazEs, ...} = ctxt |> claset_of |> rep_cs
   804     val {safeIs, safeEs, hazIs, hazEs, ...} = ctxt |> claset_of |> rep_cs
   795     val intros = safeIs @ hazIs
   805     val intros = safeIs @ hazIs
   796     val elims = map Classical.classical_rule (safeEs @ hazEs)
   806     val elims = map Classical.classical_rule (safeEs @ hazEs)
   797     val simps = ctxt |> simpset_of |> dest_ss |> #simps |> map snd
   807     val simps = ctxt |> simpset_of |> dest_ss |> #simps
   798   in (mk_fact_table I intros, mk_fact_table I elims, mk_fact_table I simps) end
   808   in
   799 
   809     (mk_fact_table I I intros,
   800 fun all_facts ctxt reserved really_all
   810      mk_fact_table I I elims,
   801               ({intro_bonus, elim_bonus, simp_bonus, ...} : relevance_fudge)
   811      mk_fact_table normalize_simp_prop snd simps)
   802               add_ths chained_ths =
   812   end
       
   813 
       
   814 fun all_facts ctxt reserved really_all add_ths chained_ths =
   803   let
   815   let
   804     val thy = Proof_Context.theory_of ctxt
   816     val thy = Proof_Context.theory_of ctxt
   805     val global_facts = Global_Theory.facts_of thy
   817     val global_facts = Global_Theory.facts_of thy
   806     val local_facts = Proof_Context.facts_of ctxt
   818     val local_facts = Proof_Context.facts_of ctxt
   807     val named_locals = local_facts |> Facts.dest_static []
   819     val named_locals = local_facts |> Facts.dest_static []
   808     val assms = Assumption.all_assms_of ctxt
   820     val assms = Assumption.all_assms_of ctxt
   809     fun is_assum th = exists (fn ct => prop_of th aconv term_of ct) assms
   821     fun is_assum th = exists (fn ct => prop_of th aconv term_of ct) assms
   810     val is_chained = member Thm.eq_thm chained_ths
   822     val is_chained = member Thm.eq_thm chained_ths
   811     val (intros, elims, simps) =
   823     val (intros, elims, simps) = clasimpset_rules_of ctxt
   812       if exists (curry (op <) 0.0) [intro_bonus, elim_bonus, simp_bonus] then
   824     fun locality_of_theorem global th =
   813         clasimpset_rules_of ctxt
   825       if is_chained th then
       
   826         Chained
       
   827       else if global then
       
   828         let val t = prop_of th in
       
   829           if Termtab.defined intros t then Intro
       
   830           else if Termtab.defined elims t then Elim
       
   831           else if Termtab.defined simps (normalize_simp_prop t) then Simp
       
   832           else General
       
   833         end
   814       else
   834       else
   815         (Termtab.empty, Termtab.empty, Termtab.empty)
   835         if is_assum th then Assum else Local
   816     fun is_good_unnamed_local th =
   836     fun is_good_unnamed_local th =
   817       not (Thm.has_name_hint th) andalso
   837       not (Thm.has_name_hint th) andalso
   818       forall (fn (_, ths) => not (member Thm.eq_thm ths th)) named_locals
   838       forall (fn (_, ths) => not (member Thm.eq_thm ths th)) named_locals
   819     val unnamed_locals =
   839     val unnamed_locals =
   820       union Thm.eq_thm (Facts.props local_facts) chained_ths
   840       union Thm.eq_thm (Facts.props local_facts) chained_ths
   840                 NONE => false
   860                 NONE => false
   841               | SOME ths' => Thm.eq_thms (ths, ths')
   861               | SOME ths' => Thm.eq_thms (ths, ths')
   842           in
   862           in
   843             pair 1
   863             pair 1
   844             #> fold (fn th => fn (j, rest) =>
   864             #> fold (fn th => fn (j, rest) =>
   845                  (j + 1,
   865                         (j + 1,
   846                   if is_theorem_bad_for_atps th andalso
   866                          if is_theorem_bad_for_atps th andalso
   847                      not (member Thm.eq_thm add_ths th) then
   867                             not (member Thm.eq_thm add_ths th) then
   848                     rest
   868                            rest
   849                   else
   869                          else
   850                     (((fn () =>
   870                            (((fn () =>
   851                           if name0 = "" then
   871                                  if name0 = "" then
   852                             th |> backquote_thm
   872                                    th |> backquote_thm
   853                           else
   873                                  else
   854                             let
   874                                    [Facts.extern ctxt facts name0,
   855                               val name1 = Facts.extern ctxt facts name0
   875                                     Name_Space.extern ctxt full_space name0,
   856                               val name2 = Name_Space.extern ctxt full_space name0
   876                                     name0]
   857                             in
   877                                    |> find_first check_thms
   858                               case find_first check_thms [name1, name2, name0] of
   878                                    |> (fn SOME name =>
   859                                 SOME name => make_name reserved multi j name
   879                                           make_name reserved multi j name
   860                               | NONE => ""
   880                                         | NONE => "")),
   861                             end),
   881                               locality_of_theorem global th),
   862                       let val t = prop_of th in
   882                               (multi, th)) :: rest)) ths
   863                         if is_chained th then
       
   864                           Chained
       
   865                         else if global then
       
   866                           if Termtab.defined intros t then Intro
       
   867                           else if Termtab.defined elims t then Elim
       
   868                           else if Termtab.defined simps t then Simp
       
   869                           else General
       
   870                         else
       
   871                           if is_assum th then Assum else Local
       
   872                       end),
       
   873                       (multi, th)) :: rest)) ths
       
   874             #> snd
   883             #> snd
   875           end)
   884           end)
   876   in
   885   in
   877     [] |> add_facts false fold local_facts (unnamed_locals @ named_locals)
   886     [] |> add_facts false fold local_facts (unnamed_locals @ named_locals)
   878        |> add_facts true Facts.fold_static global_facts global_facts
   887        |> add_facts true Facts.fold_static global_facts global_facts
   903     val facts =
   912     val facts =
   904       (if only then
   913       (if only then
   905          maps (map (fn ((name, loc), th) => ((K name, loc), (true, th)))
   914          maps (map (fn ((name, loc), th) => ((K name, loc), (true, th)))
   906                o fact_from_ref ctxt reserved chained_ths) add
   915                o fact_from_ref ctxt reserved chained_ths) add
   907        else
   916        else
   908          all_facts ctxt reserved false fudge add_ths chained_ths)
   917          all_facts ctxt reserved false add_ths chained_ths)
   909       |> instantiate_inducts
   918       |> instantiate_inducts
   910          ? maps (instantiate_if_induct_rule ctxt ind_stmt ind_stmt_xs)
   919          ? maps (instantiate_if_induct_rule ctxt ind_stmt ind_stmt_xs)
   911       |> rearrange_facts ctxt (respect_no_atp andalso not only)
   920       |> rearrange_facts ctxt (respect_no_atp andalso not only)
   912       |> uniquify
   921       |> uniquify
   913   in
   922   in