src/HOL/Tools/Sledgehammer/sledgehammer_filter.ML
author blanchet
Wed, 11 Jul 2012 21:43:19 +0200
changeset 48248 b6eb45a52c28
parent 48237 d7ad89f60768
child 48250 1065c307fafe
permissions -rw-r--r--
split relevance filter code into three files
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38988
483879af0643 finished renaming
blanchet
parents: 38986
diff changeset
     1
(*  Title:      HOL/Tools/Sledgehammer/sledgehammer_filter.ML
38027
505657ddb047 standardize "Author" tags
blanchet
parents: 37995
diff changeset
     2
    Author:     Jia Meng, Cambridge University Computer Laboratory and NICTA
36393
be73a2b2443b support readable names even when Isar proof reconstruction is enabled -- useful for debugging
blanchet
parents: 36227
diff changeset
     3
    Author:     Jasmin Blanchette, TU Muenchen
39958
88c9aa5666de tuned comments
blanchet
parents: 39946
diff changeset
     4
48248
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
     5
Sledgehammer's hybrid relevance filter.
33309
5f67433e6dd8 proper header;
wenzelm
parents: 33306
diff changeset
     6
*)
15452
e2a721567f67 Jia Meng: delta simpsets and clasets
paulson
parents: 15347
diff changeset
     7
38988
483879af0643 finished renaming
blanchet
parents: 38986
diff changeset
     8
signature SLEDGEHAMMER_FILTER =
16802
6eeee59dac4c use Toplevel.print_state_hook instead of adhoc Proof.atp_hook;
wenzelm
parents: 16767
diff changeset
     9
sig
46388
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    10
  type status = ATP_Problem_Generate.status
46340
cac402c486b0 separate orthogonal components
blanchet
parents: 46320
diff changeset
    11
  type stature = ATP_Problem_Generate.stature
48248
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    12
  type relevance_fudge = Sledgehammer_Filter_Iter.relevance_fudge
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    13
  type relevance_override = Sledgehammer_Filter_Iter.relevance_override
38752
6628adcae4a7 consider "locality" when assigning weights to facts
blanchet
parents: 38751
diff changeset
    14
44462
d9a657c44380 more reliable "sledgehammer\_tac" reconstruction, by avoiding "insert_tac"
blanchet
parents: 44400
diff changeset
    15
  val no_relevance_override : relevance_override
40205
277508b07418 if "debug" is on, print list of relevant facts (poweruser request);
blanchet
parents: 40204
diff changeset
    16
  val fact_from_ref :
46388
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    17
    Proof.context -> unit Symtab.table -> thm list -> status Termtab.table
46340
cac402c486b0 separate orthogonal components
blanchet
parents: 46320
diff changeset
    18
    -> Facts.ref * Attrib.src list -> ((string * stature) * thm) list
41767
44b2a0385001 export useful function (needed in a Sledgehammer-related experiment)
blanchet
parents: 41491
diff changeset
    19
  val all_facts :
46734
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
    20
    Proof.context -> bool -> 'a Symtab.table -> bool -> thm list
47774
blanchet
parents: 47148
diff changeset
    21
    -> thm list -> status Termtab.table
blanchet
parents: 47148
diff changeset
    22
    -> (((unit -> string) * stature) * thm) list
48248
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    23
  val clasimpset_rule_table_of : Proof.context -> status Termtab.table
48237
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
    24
  val maybe_instantiate_inducts :
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
    25
    Proof.context -> term list -> term -> (((unit -> string) * 'a) * thm) list
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
    26
    -> (((unit -> string) * 'a) * thm) list
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
    27
  val maybe_filter_no_atps : Proof.context -> ('a * thm) list -> ('a * thm) list
43351
b19d95b4d736 compute the set of base facts only once (instead of three times in parallel) -- this saves about .5 s of CPU time, albeit much less clock wall time
blanchet
parents: 43324
diff changeset
    28
  val nearly_all_facts :
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
    29
    Proof.context -> bool -> relevance_override -> thm list -> term list -> term
46340
cac402c486b0 separate orthogonal components
blanchet
parents: 46320
diff changeset
    30
    -> (((unit -> string) * stature) * thm) list
37347
635425a442e8 show more respect for user-specified facts, even if they could lead to unsound proofs + don't throw away "unsound" theorems in "full_type" mode, since they are then sound
blanchet
parents: 37345
diff changeset
    31
  val relevant_facts :
44625
4a1132815a70 more tuning
blanchet
parents: 44586
diff changeset
    32
    Proof.context -> real * real -> int
41336
0ea5b9c7d233 proper handling of the arguments of SMT builtins -- for numerals, ignore the arguments (Pls, Bit0, Bit1, ..), for functions, consider them;
blanchet
parents: 41279
diff changeset
    33
    -> (string * typ -> term list -> bool * term list) -> relevance_fudge
41066
3890ef4e02f9 pass constant arguments to the built-in check function, cf. d2b1fc1b8e19
blanchet
parents: 40418
diff changeset
    34
    -> relevance_override -> thm list -> term list -> term
46340
cac402c486b0 separate orthogonal components
blanchet
parents: 46320
diff changeset
    35
    -> (((unit -> string) * stature) * thm) list
cac402c486b0 separate orthogonal components
blanchet
parents: 46320
diff changeset
    36
    -> ((string * stature) * thm) list
15347
14585bc8fa09 resolution package tools by Jia Meng
paulson
parents:
diff changeset
    37
end;
14585bc8fa09 resolution package tools by Jia Meng
paulson
parents:
diff changeset
    38
38988
483879af0643 finished renaming
blanchet
parents: 38986
diff changeset
    39
structure Sledgehammer_Filter : SLEDGEHAMMER_FILTER =
15347
14585bc8fa09 resolution package tools by Jia Meng
paulson
parents:
diff changeset
    40
struct
14585bc8fa09 resolution package tools by Jia Meng
paulson
parents:
diff changeset
    41
46320
0b8b73b49848 renamed two files to make room for a new file
blanchet
parents: 46217
diff changeset
    42
open ATP_Problem_Generate
44934
blanchet
parents: 44785
diff changeset
    43
open Metis_Tactic
38652
e063be321438 perform eta-expansion of quantifier bodies in Sledgehammer translation when needed + transform elim rules later;
blanchet
parents: 38644
diff changeset
    44
open Sledgehammer_Util
48248
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    45
open Sledgehammer_Filter_Iter
44462
d9a657c44380 more reliable "sledgehammer\_tac" reconstruction, by avoiding "insert_tac"
blanchet
parents: 44400
diff changeset
    46
37616
c8d2d84d6011 always perform relevance filtering on original formulas
blanchet
parents: 37580
diff changeset
    47
val sledgehammer_prefix = "Sledgehammer" ^ Long_Name.separator
c8d2d84d6011 always perform relevance filtering on original formulas
blanchet
parents: 37580
diff changeset
    48
48248
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    49
val no_relevance_override = {add = [], del = [], only = false}
46388
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    50
40227
e31e3f0071d4 support non-identifier-like fact names in Sledgehammer (e.g., "my lemma") by quoting them
blanchet
parents: 40205
diff changeset
    51
fun needs_quoting reserved s =
40375
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
    52
  Symtab.defined reserved s orelse
42290
b1f544c84040 discontinued special treatment of structure Lexicon;
wenzelm
parents: 41999
diff changeset
    53
  exists (not o Lexicon.is_identifier) (Long_Name.explode s)
40227
e31e3f0071d4 support non-identifier-like fact names in Sledgehammer (e.g., "my lemma") by quoting them
blanchet
parents: 40205
diff changeset
    54
40375
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
    55
fun make_name reserved multi j name =
40227
e31e3f0071d4 support non-identifier-like fact names in Sledgehammer (e.g., "my lemma") by quoting them
blanchet
parents: 40205
diff changeset
    56
  (name |> needs_quoting reserved name ? quote) ^
41491
a2ad5b824051 eliminated Int.toString;
wenzelm
parents: 41336
diff changeset
    57
  (if multi then "(" ^ string_of_int j ^ ")" else "")
38744
2b6333f78a9e make relevance filter work in term of a "max_relevant" option + use Vampire SOS;
blanchet
parents: 38743
diff changeset
    58
40375
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
    59
fun explode_interval _ (Facts.FromTo (i, j)) = i upto j
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
    60
  | explode_interval max (Facts.From i) = i upto i + max - 1
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
    61
  | explode_interval _ (Facts.Single i) = [i]
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
    62
41279
e0400b05a62c escape backticks in altstrings
blanchet
parents: 41273
diff changeset
    63
val backquote =
e0400b05a62c escape backticks in altstrings
blanchet
parents: 41273
diff changeset
    64
  raw_explode #> map (fn "`" => "\\`" | s => s) #> implode #> enclose "`" "`"
46388
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    65
48248
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    66
(* unfolding these can yield really huge terms *)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    67
val risky_defs = @{thms Bit0_def Bit1_def}
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    68
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    69
fun is_rec_eq lhs = Term.exists_subterm (curry (op =) (head_of lhs))
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    70
fun is_rec_def (@{const Trueprop} $ t) = is_rec_def t
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    71
  | is_rec_def (@{const ==>} $ _ $ t2) = is_rec_def t2
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    72
  | is_rec_def (Const (@{const_name "=="}, _) $ t1 $ t2) = is_rec_eq t1 t2
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    73
  | is_rec_def (Const (@{const_name HOL.eq}, _) $ t1 $ t2) = is_rec_eq t1 t2
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    74
  | is_rec_def _ = false
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
    75
46388
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    76
fun is_assum assms th = exists (fn ct => prop_of th aconv term_of ct) assms
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    77
fun is_chained chained_ths = member Thm.eq_thm_prop chained_ths
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    78
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    79
fun scope_of_thm global assms chained_ths th =
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    80
  if is_chained chained_ths th then Chained
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    81
  else if global then Global
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    82
  else if is_assum assms th then Assum
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    83
  else Local
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    84
47904
67663c968d70 distinguish between instantiated and uninstantiated inductions -- the latter are OK for first-order provers
blanchet
parents: 47774
diff changeset
    85
val may_be_induction =
67663c968d70 distinguish between instantiated and uninstantiated inductions -- the latter are OK for first-order provers
blanchet
parents: 47774
diff changeset
    86
  exists_subterm (fn Var (_, Type (@{type_name fun}, [_, T])) =>
67663c968d70 distinguish between instantiated and uninstantiated inductions -- the latter are OK for first-order provers
blanchet
parents: 47774
diff changeset
    87
                     body_type T = @{typ bool}
67663c968d70 distinguish between instantiated and uninstantiated inductions -- the latter are OK for first-order provers
blanchet
parents: 47774
diff changeset
    88
                   | _ => false)
67663c968d70 distinguish between instantiated and uninstantiated inductions -- the latter are OK for first-order provers
blanchet
parents: 47774
diff changeset
    89
46388
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    90
fun status_of_thm css_table name th =
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    91
  (* FIXME: use structured name *)
47904
67663c968d70 distinguish between instantiated and uninstantiated inductions -- the latter are OK for first-order provers
blanchet
parents: 47774
diff changeset
    92
  if (String.isSubstring ".induct" name orelse
67663c968d70 distinguish between instantiated and uninstantiated inductions -- the latter are OK for first-order provers
blanchet
parents: 47774
diff changeset
    93
      String.isSubstring ".inducts" name) andalso
67663c968d70 distinguish between instantiated and uninstantiated inductions -- the latter are OK for first-order provers
blanchet
parents: 47774
diff changeset
    94
     may_be_induction (prop_of th) then
47148
7b5846065c1b be less forceful about ":lt" to make infinite loops less likely (could still fail with mutually recursive tail rec functions)
blanchet
parents: 47073
diff changeset
    95
    Induction
46388
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    96
  else case Termtab.lookup css_table (prop_of th) of
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    97
    SOME status => status
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    98
  | NONE => General
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
    99
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   100
fun stature_of_thm global assms chained_ths css_table name th =
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   101
  (scope_of_thm global assms chained_ths th, status_of_thm css_table name th)
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   102
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   103
fun fact_from_ref ctxt reserved chained_ths css_table (xthm as (xref, args)) =
38744
2b6333f78a9e make relevance filter work in term of a "max_relevant" option + use Vampire SOS;
blanchet
parents: 38743
diff changeset
   104
  let
38996
6905ba37376c generalize theorem argument parsing syntax
blanchet
parents: 38994
diff changeset
   105
    val ths = Attrib.eval_thms ctxt [xthm]
6905ba37376c generalize theorem argument parsing syntax
blanchet
parents: 38994
diff changeset
   106
    val bracket =
41999
3c029ef9e0f2 added "simp:", "intro:", and "elim:" to "try" command
blanchet
parents: 41989
diff changeset
   107
      map (enclose "[" "]" o Pretty.str_of o Args.pretty_src ctxt) args
3c029ef9e0f2 added "simp:", "intro:", and "elim:" to "try" command
blanchet
parents: 41989
diff changeset
   108
      |> implode
40375
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
   109
    fun nth_name j =
38996
6905ba37376c generalize theorem argument parsing syntax
blanchet
parents: 38994
diff changeset
   110
      case xref of
41279
e0400b05a62c escape backticks in altstrings
blanchet
parents: 41273
diff changeset
   111
        Facts.Fact s => backquote s ^ bracket
38996
6905ba37376c generalize theorem argument parsing syntax
blanchet
parents: 38994
diff changeset
   112
      | Facts.Named (("", _), _) => "[" ^ bracket ^ "]"
40375
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
   113
      | Facts.Named ((name, _), NONE) =>
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
   114
        make_name reserved (length ths > 1) (j + 1) name ^ bracket
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
   115
      | Facts.Named ((name, _), SOME intervals) =>
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
   116
        make_name reserved true
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
   117
                 (nth (maps (explode_interval (length ths)) intervals) j) name ^
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
   118
        bracket
38744
2b6333f78a9e make relevance filter work in term of a "max_relevant" option + use Vampire SOS;
blanchet
parents: 38743
diff changeset
   119
  in
40375
db690d38e4b9 fixed handling of theorem references such as "foo bar" (with quotes), "foo bar(2)", and "foo bar(2)"(2)
blanchet
parents: 40373
diff changeset
   120
    (ths, (0, []))
38752
6628adcae4a7 consider "locality" when assigning weights to facts
blanchet
parents: 38751
diff changeset
   121
    |-> fold (fn th => fn (j, rest) =>
46388
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   122
                 let val name = nth_name j in
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   123
                   (j + 1, ((name, stature_of_thm false [] chained_ths
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   124
                                             css_table name th), th) :: rest)
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   125
                 end)
38744
2b6333f78a9e make relevance filter work in term of a "max_relevant" option + use Vampire SOS;
blanchet
parents: 38743
diff changeset
   126
    |> snd
38699
27378b4a776b compute names lazily;
blanchet
parents: 38698
diff changeset
   127
  end
37616
c8d2d84d6011 always perform relevance filtering on original formulas
blanchet
parents: 37580
diff changeset
   128
20757
fe84fe0dfd30 Definitions produced by packages are now blacklisted.
paulson
parents: 20661
diff changeset
   129
(*Reject theorems with names like "List.filter.filter_list_def" or
21690
552d20ff9a95 Removal of theorem tagging, which the ATP linkup no longer requires.
paulson
parents: 21588
diff changeset
   130
  "Accessible_Part.acc.defs", as these are definitions arising from packages.*)
20757
fe84fe0dfd30 Definitions produced by packages are now blacklisted.
paulson
parents: 20661
diff changeset
   131
fun is_package_def a =
40205
277508b07418 if "debug" is on, print list of relevant facts (poweruser request);
blanchet
parents: 40204
diff changeset
   132
  let val names = Long_Name.explode a in
277508b07418 if "debug" is on, print list of relevant facts (poweruser request);
blanchet
parents: 40204
diff changeset
   133
    (length names > 2 andalso not (hd names = "local") andalso
277508b07418 if "debug" is on, print list of relevant facts (poweruser request);
blanchet
parents: 40204
diff changeset
   134
     String.isSuffix "_def" a) orelse String.isSuffix "_defs" a
277508b07418 if "debug" is on, print list of relevant facts (poweruser request);
blanchet
parents: 40204
diff changeset
   135
  end
20757
fe84fe0dfd30 Definitions produced by packages are now blacklisted.
paulson
parents: 20661
diff changeset
   136
37626
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   137
(* FIXME: put other record thms here, or declare as "no_atp" *)
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   138
fun multi_base_blacklist ctxt ho_atp =
41199
4698d12dd860 instantiate induction rules automatically
blanchet
parents: 41167
diff changeset
   139
  ["defs", "select_defs", "update_defs", "split", "splits", "split_asm",
4698d12dd860 instantiate induction rules automatically
blanchet
parents: 41167
diff changeset
   140
   "cases", "ext_cases", "eq.simps", "eq.refl", "nchotomy", "case_cong",
4698d12dd860 instantiate induction rules automatically
blanchet
parents: 41167
diff changeset
   141
   "weak_case_cong"]
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   142
  |> not (ho_atp orelse (Config.get ctxt instantiate_inducts)) ?
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   143
        append ["induct", "inducts"]
38682
3a203da3f89b weed out junk in relevance filter
blanchet
parents: 38681
diff changeset
   144
  |> map (prefix ".")
37626
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   145
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   146
val max_lambda_nesting = 3 (*only applies if not ho_atp*)
37626
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   147
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   148
fun term_has_too_many_lambdas max (t1 $ t2) =
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   149
    exists (term_has_too_many_lambdas max) [t1, t2]
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   150
  | term_has_too_many_lambdas max (Abs (_, _, t)) =
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   151
    max = 0 orelse term_has_too_many_lambdas (max - 1) t
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   152
  | term_has_too_many_lambdas _ _ = false
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   153
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   154
(* Don't count nested lambdas at the level of formulas, since they are
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   155
   quantifiers. *)
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   156
fun formula_has_too_many_lambdas true _ _ = false (*i.e. ho_atp*)
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   157
  | formula_has_too_many_lambdas _ Ts (Abs (_, T, t)) =
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   158
      formula_has_too_many_lambdas false (T :: Ts) t
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   159
  | formula_has_too_many_lambdas _ Ts t =
41273
35ce17cd7967 made the relevance filter treat unatomizable facts like "atomize_all" properly (these result in problems that get E spinning seemingly forever);
blanchet
parents: 41211
diff changeset
   160
    if member (op =) [HOLogic.boolT, propT] (fastype_of1 (Ts, t)) then
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   161
      exists (formula_has_too_many_lambdas false Ts) (#2 (strip_comb t))
37626
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   162
    else
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   163
      term_has_too_many_lambdas max_lambda_nesting t
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   164
38692
89d3550d8e16 cosmetics
blanchet
parents: 38689
diff changeset
   165
(* The max apply depth of any "metis" call in "Metis_Examples" (on 2007-10-31)
37626
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   166
   was 11. *)
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   167
val max_apply_depth = 15
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   168
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   169
fun apply_depth (f $ t) = Int.max (apply_depth f, apply_depth t + 1)
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   170
  | apply_depth (Abs (_, _, t)) = apply_depth t
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   171
  | apply_depth _ = 0
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   172
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   173
fun is_formula_too_complex ho_atp t =
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   174
  apply_depth t > max_apply_depth orelse formula_has_too_many_lambdas ho_atp [] t
37626
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   175
39946
78faa9b31202 move Metis into Plain
blanchet
parents: 39896
diff changeset
   176
(* FIXME: Extend to "Meson" and "Metis" *)
37543
2e733b0a963c a76ace919f1c wasn't quite right; second try
blanchet
parents: 37538
diff changeset
   177
val exists_sledgehammer_const =
37626
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   178
  exists_Const (fn (s, _) => String.isPrefix sledgehammer_prefix s)
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   179
38904
5e760c0f81a6 rule out low-level class facts
blanchet
parents: 38901
diff changeset
   180
(* FIXME: make more reliable *)
5e760c0f81a6 rule out low-level class facts
blanchet
parents: 38901
diff changeset
   181
val exists_low_level_class_const =
5e760c0f81a6 rule out low-level class facts
blanchet
parents: 38901
diff changeset
   182
  exists_Const (fn (s, _) =>
47976
6b13451135a9 tuned names
blanchet
parents: 47953
diff changeset
   183
     s = @{const_name equal_class.equal} orelse
38904
5e760c0f81a6 rule out low-level class facts
blanchet
parents: 38901
diff changeset
   184
     String.isSubstring (Long_Name.separator ^ "class" ^ Long_Name.separator) s)
5e760c0f81a6 rule out low-level class facts
blanchet
parents: 38901
diff changeset
   185
38821
d0275b6c4e9d avoid needless "that" fact
blanchet
parents: 38820
diff changeset
   186
fun is_metastrange_theorem th =
37626
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   187
  case head_of (concl_of th) of
43576
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   188
    Const (s, _) => (s <> @{const_name Trueprop} andalso
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   189
                     s <> @{const_name "=="})
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   190
  | _ => false
37626
1146291fe718 move blacklisting completely out of the clausifier;
blanchet
parents: 37616
diff changeset
   191
38821
d0275b6c4e9d avoid needless "that" fact
blanchet
parents: 38820
diff changeset
   192
fun is_that_fact th =
d0275b6c4e9d avoid needless "that" fact
blanchet
parents: 38820
diff changeset
   193
  String.isSuffix (Long_Name.separator ^ Obtain.thatN) (Thm.get_name_hint th)
d0275b6c4e9d avoid needless "that" fact
blanchet
parents: 38820
diff changeset
   194
  andalso exists_subterm (fn Free (s, _) => s = Name.skolem Auto_Bind.thesisN
d0275b6c4e9d avoid needless "that" fact
blanchet
parents: 38820
diff changeset
   195
                           | _ => false) (prop_of th)
d0275b6c4e9d avoid needless "that" fact
blanchet
parents: 38820
diff changeset
   196
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   197
fun is_theorem_bad_for_atps ho_atp exporter thm =
43576
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   198
  is_metastrange_theorem thm orelse
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   199
  (not exporter andalso
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   200
   let val t = prop_of thm in
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   201
     is_formula_too_complex ho_atp t orelse exists_type type_has_top_sort t orelse
43576
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   202
     exists_sledgehammer_const t orelse exists_low_level_class_const t orelse
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   203
     is_that_fact thm
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   204
   end)
38627
760a2d5cc671 make sure minimizer facts go through "transform_elim_theorems"
blanchet
parents: 38617
diff changeset
   205
48248
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   206
fun string_for_term ctxt t =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   207
  Print_Mode.setmp (filter (curry (op =) Symbol.xsymbolsN)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   208
                   (print_mode_value ())) (Syntax.string_of_term ctxt) t
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   209
  |> String.translate (fn c => if Char.isPrint c then str c else "")
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   210
  |> simplify_spaces
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   211
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   212
(* This is a terrible hack. Free variables are sometimes coded as "M__" when
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   213
   they are displayed as "M" and we want to avoid clashes with these. But
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   214
   sometimes it's even worse: "Ma__" encodes "M". So we simply reserve all
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   215
   prefixes of all free variables. In the worse case scenario, where the fact
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   216
   won't be resolved correctly, the user can fix it manually, e.g., by naming
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   217
   the fact in question. Ideally we would need nothing of it, but backticks
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   218
   simply don't work with schematic variables. *)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   219
fun all_prefixes_of s =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   220
  map (fn i => String.extract (s, 0, SOME i)) (1 upto size s - 1)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   221
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   222
fun close_form t =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   223
  (t, [] |> Term.add_free_names t |> maps all_prefixes_of)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   224
  |> fold (fn ((s, i), T) => fn (t', taken) =>
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   225
              let val s' = singleton (Name.variant_list taken) s in
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   226
                ((if fastype_of t' = HOLogic.boolT then HOLogic.all_const
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   227
                  else Logic.all_const) T
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   228
                 $ Abs (s', T, abstract_over (Var ((s, i), T), t')),
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   229
                 s' :: taken)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   230
              end)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   231
          (Term.add_vars t [] |> sort_wrt (fst o fst))
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   232
  |> fst
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   233
46734
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   234
fun all_facts ctxt ho_atp reserved exporter add_ths chained_ths css_table =
38627
760a2d5cc671 make sure minimizer facts go through "transform_elim_theorems"
blanchet
parents: 38617
diff changeset
   235
  let
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 42358
diff changeset
   236
    val thy = Proof_Context.theory_of ctxt
39557
fe5722fce758 renamed structure PureThy to Pure_Thy and moved most content to Global_Theory, to emphasize that this is global-only;
wenzelm
parents: 39367
diff changeset
   237
    val global_facts = Global_Theory.facts_of thy
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 42358
diff changeset
   238
    val local_facts = Proof_Context.facts_of ctxt
38644
25bbbaf7ce65 don't penalize abstractions in relevance filter + support nameless `foo`-style facts
blanchet
parents: 38629
diff changeset
   239
    val named_locals = local_facts |> Facts.dest_static []
38993
504b9e1efd33 give priority to assumptions in structured proofs
blanchet
parents: 38992
diff changeset
   240
    val assms = Assumption.all_assms_of ctxt
38738
0ce517c1970f make sure that "undo_ascii_of" is the inverse of "ascii_of", also for non-printable characters -- and avoid those in ``-style facts
blanchet
parents: 38699
diff changeset
   241
    fun is_good_unnamed_local th =
38820
d0f98bd81a85 add nameless chained facts to the pool of things known to Sledgehammer
blanchet
parents: 38819
diff changeset
   242
      not (Thm.has_name_hint th) andalso
42957
c693f9b7674a use "eq_thm_prop" for slacker comparison -- ensures that backtick-quoted chained facts are recognized in the minimizer, among other things
blanchet
parents: 42952
diff changeset
   243
      forall (fn (_, ths) => not (member Thm.eq_thm_prop ths th)) named_locals
38644
25bbbaf7ce65 don't penalize abstractions in relevance filter + support nameless `foo`-style facts
blanchet
parents: 38629
diff changeset
   244
    val unnamed_locals =
42957
c693f9b7674a use "eq_thm_prop" for slacker comparison -- ensures that backtick-quoted chained facts are recognized in the minimizer, among other things
blanchet
parents: 42952
diff changeset
   245
      union Thm.eq_thm_prop (Facts.props local_facts) chained_ths
38820
d0f98bd81a85 add nameless chained facts to the pool of things known to Sledgehammer
blanchet
parents: 38819
diff changeset
   246
      |> filter is_good_unnamed_local |> map (pair "" o single)
38627
760a2d5cc671 make sure minimizer facts go through "transform_elim_theorems"
blanchet
parents: 38617
diff changeset
   247
    val full_space =
38738
0ce517c1970f make sure that "undo_ascii_of" is the inverse of "ascii_of", also for non-printable characters -- and avoid those in ``-style facts
blanchet
parents: 38699
diff changeset
   248
      Name_Space.merge (Facts.space_of global_facts, Facts.space_of local_facts)
38752
6628adcae4a7 consider "locality" when assigning weights to facts
blanchet
parents: 38751
diff changeset
   249
    fun add_facts global foldx facts =
38699
27378b4a776b compute names lazily;
blanchet
parents: 38698
diff changeset
   250
      foldx (fn (name0, ths) =>
43576
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   251
        if not exporter andalso name0 <> "" andalso
42957
c693f9b7674a use "eq_thm_prop" for slacker comparison -- ensures that backtick-quoted chained facts are recognized in the minimizer, among other things
blanchet
parents: 42952
diff changeset
   252
           forall (not o member Thm.eq_thm_prop add_ths) ths andalso
38699
27378b4a776b compute names lazily;
blanchet
parents: 38698
diff changeset
   253
           (Facts.is_concealed facts name0 orelse
42728
44cd74a419ce added configuration options for experimental features
blanchet
parents: 42702
diff changeset
   254
            (not (Config.get ctxt ignore_no_atp) andalso
44cd74a419ce added configuration options for experimental features
blanchet
parents: 42702
diff changeset
   255
             is_package_def name0) orelse
44cd74a419ce added configuration options for experimental features
blanchet
parents: 42702
diff changeset
   256
            exists (fn s => String.isSuffix s name0)
46976
80123a220219 'definition' no longer exports the foundational "raw_def";
wenzelm
parents: 46734
diff changeset
   257
                   (multi_base_blacklist ctxt ho_atp)) then
38627
760a2d5cc671 make sure minimizer facts go through "transform_elim_theorems"
blanchet
parents: 38617
diff changeset
   258
          I
760a2d5cc671 make sure minimizer facts go through "transform_elim_theorems"
blanchet
parents: 38617
diff changeset
   259
        else
760a2d5cc671 make sure minimizer facts go through "transform_elim_theorems"
blanchet
parents: 38617
diff changeset
   260
          let
38699
27378b4a776b compute names lazily;
blanchet
parents: 38698
diff changeset
   261
            val multi = length ths > 1
41279
e0400b05a62c escape backticks in altstrings
blanchet
parents: 41273
diff changeset
   262
            val backquote_thm =
e0400b05a62c escape backticks in altstrings
blanchet
parents: 41273
diff changeset
   263
              backquote o string_for_term ctxt o close_form o prop_of
38699
27378b4a776b compute names lazily;
blanchet
parents: 38698
diff changeset
   264
            fun check_thms a =
42361
23f352990944 modernized structure Proof_Context;
wenzelm
parents: 42358
diff changeset
   265
              case try (Proof_Context.get_thms ctxt) a of
38699
27378b4a776b compute names lazily;
blanchet
parents: 38698
diff changeset
   266
                NONE => false
42957
c693f9b7674a use "eq_thm_prop" for slacker comparison -- ensures that backtick-quoted chained facts are recognized in the minimizer, among other things
blanchet
parents: 42952
diff changeset
   267
              | SOME ths' => eq_list Thm.eq_thm_prop (ths, ths')
38627
760a2d5cc671 make sure minimizer facts go through "transform_elim_theorems"
blanchet
parents: 38617
diff changeset
   268
          in
38699
27378b4a776b compute names lazily;
blanchet
parents: 38698
diff changeset
   269
            pair 1
43245
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   270
            #> fold (fn th => fn (j, (multis, unis)) =>
42641
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   271
                        (j + 1,
43576
ebeda6275027 don't export any metastrange or other nonatomizable formulas, since these don't help proving normal things, they are somewhat broken in the ATP output, and they are atypical
blanchet
parents: 43492
diff changeset
   272
                         if not (member Thm.eq_thm_prop add_ths th) andalso
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   273
                            is_theorem_bad_for_atps ho_atp exporter th then
43245
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   274
                           (multis, unis)
42641
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   275
                         else
43245
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   276
                           let
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   277
                             val new =
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   278
                               (((fn () =>
42641
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   279
                                 if name0 = "" then
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   280
                                   th |> backquote_thm
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   281
                                 else
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   282
                                   [Facts.extern ctxt facts name0,
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   283
                                    Name_Space.extern ctxt full_space name0,
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   284
                                    name0]
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   285
                                   |> find_first check_thms
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   286
                                   |> (fn SOME name =>
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   287
                                          make_name reserved multi j name
2cd4e6463842 recognize simplification rules even if they look a bit different from the theorems in the theories (meta equality, variable numbers)
blanchet
parents: 42638
diff changeset
   288
                                        | NONE => "")),
46388
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   289
                                stature_of_thm global assms chained_ths
e7445478d90b proper statuses for "fact_from_ref"
blanchet
parents: 46379
diff changeset
   290
                                               css_table name0 th), th)
43245
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   291
                           in
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   292
                             if multi then (new :: multis, unis)
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   293
                             else (multis, new :: unis)
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   294
                           end)) ths
38699
27378b4a776b compute names lazily;
blanchet
parents: 38698
diff changeset
   295
            #> snd
38627
760a2d5cc671 make sure minimizer facts go through "transform_elim_theorems"
blanchet
parents: 38617
diff changeset
   296
          end)
38644
25bbbaf7ce65 don't penalize abstractions in relevance filter + support nameless `foo`-style facts
blanchet
parents: 38629
diff changeset
   297
  in
43245
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   298
    (* The single-name theorems go after the multiple-name ones, so that single
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   299
       names are preferred when both are available. *)
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   300
    ([], []) |> add_facts false fold local_facts (unnamed_locals @ named_locals)
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   301
             |> add_facts true Facts.fold_static global_facts global_facts
cef69d31bfa4 optimized the relevance filter a little bit
blanchet
parents: 43085
diff changeset
   302
             |> op @
38644
25bbbaf7ce65 don't penalize abstractions in relevance filter + support nameless `foo`-style facts
blanchet
parents: 38629
diff changeset
   303
  end
38627
760a2d5cc671 make sure minimizer facts go through "transform_elim_theorems"
blanchet
parents: 38617
diff changeset
   304
48248
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   305
fun clasimpset_rule_table_of ctxt =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   306
  let
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   307
    val thy = Proof_Context.theory_of ctxt
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   308
    val atomize = HOLogic.mk_Trueprop o Object_Logic.atomize_term thy
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   309
    fun add stature normalizers get_th =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   310
      fold (fn rule =>
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   311
               let
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   312
                 val th = rule |> get_th
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   313
                 val t =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   314
                   th |> Thm.maxidx_of th > 0 ? zero_var_indexes |> prop_of
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   315
               in
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   316
                 fold (fn normalize => Termtab.update (normalize t, stature))
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   317
                      (I :: normalizers)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   318
               end)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   319
    val {safeIs, (* safeEs, *) hazIs, (* hazEs, *) ...} =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   320
      ctxt |> claset_of |> Classical.rep_cs
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   321
    val intros = Item_Net.content safeIs @ Item_Net.content hazIs
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   322
(* Add once it is used:
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   323
    val elims =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   324
      Item_Net.content safeEs @ Item_Net.content hazEs
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   325
      |> map Classical.classical_rule
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   326
*)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   327
    val simps = ctxt |> simpset_of |> dest_ss |> #simps
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   328
    val specs = ctxt |> Spec_Rules.get
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   329
    val (rec_defs, nonrec_defs) =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   330
      specs |> filter (curry (op =) Spec_Rules.Equational o fst)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   331
            |> maps (snd o snd)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   332
            |> filter_out (member Thm.eq_thm_prop risky_defs)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   333
            |> List.partition (is_rec_def o prop_of)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   334
    val spec_intros =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   335
      specs |> filter (member (op =) [Spec_Rules.Inductive,
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   336
                                      Spec_Rules.Co_Inductive] o fst)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   337
            |> maps (snd o snd)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   338
  in
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   339
    Termtab.empty |> add Simp [atomize] snd simps
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   340
                  |> add Simp [] I rec_defs
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   341
                  |> add Def [] I nonrec_defs
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   342
(* Add once it is used:
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   343
                  |> add Elim [] I elims
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   344
*)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   345
                  |> add Intro [] I intros
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   346
                  |> add Inductive [] I spec_intros
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   347
  end
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   348
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   349
fun uniquify xs =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   350
  Termtab.fold (cons o snd)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   351
               (fold (Termtab.update o `(prop_of o snd)) xs Termtab.empty) []
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   352
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   353
fun struct_induct_rule_on th =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   354
  case Logic.strip_horn (prop_of th) of
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   355
    (prems, @{const Trueprop}
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   356
            $ ((p as Var ((p_name, 0), _)) $ (a as Var (_, ind_T)))) =>
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   357
    if not (is_TVar ind_T) andalso length prems > 1 andalso
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   358
       exists (exists_subterm (curry (op aconv) p)) prems andalso
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   359
       not (exists (exists_subterm (curry (op aconv) a)) prems) then
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   360
      SOME (p_name, ind_T)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   361
    else
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   362
      NONE
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   363
  | _ => NONE
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   364
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   365
fun instantiate_induct_rule ctxt concl_prop p_name ((name, stature), th) ind_x =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   366
  let
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   367
    fun varify_noninducts (t as Free (s, T)) =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   368
        if (s, T) = ind_x orelse can dest_funT T then t else Var ((s, 0), T)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   369
      | varify_noninducts t = t
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   370
    val p_inst =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   371
      concl_prop |> map_aterms varify_noninducts |> close_form
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   372
                 |> lambda (Free ind_x)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   373
                 |> string_for_term ctxt
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   374
  in
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   375
    ((fn () => name () ^ "[where " ^ p_name ^ " = " ^ quote p_inst ^ "]",
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   376
      stature), th |> read_instantiate ctxt [((p_name, 0), p_inst)])
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   377
  end
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   378
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   379
fun type_match thy (T1, T2) =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   380
  (Sign.typ_match thy (T2, T1) Vartab.empty; true)
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   381
  handle Type.TYPE_MATCH => false
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   382
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   383
fun instantiate_if_induct_rule ctxt stmt stmt_xs (ax as (_, th)) =
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   384
  case struct_induct_rule_on th of
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   385
    SOME (p_name, ind_T) =>
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   386
    let val thy = Proof_Context.theory_of ctxt in
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   387
      stmt_xs |> filter (fn (_, T) => type_match thy (T, ind_T))
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   388
              |> map_filter (try (instantiate_induct_rule ctxt stmt p_name ax))
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   389
    end
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   390
  | NONE => [ax]
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   391
41199
4698d12dd860 instantiate induction rules automatically
blanchet
parents: 41167
diff changeset
   392
fun external_frees t =
4698d12dd860 instantiate induction rules automatically
blanchet
parents: 41167
diff changeset
   393
  [] |> Term.add_frees t |> filter_out (can Name.dest_internal o fst)
4698d12dd860 instantiate induction rules automatically
blanchet
parents: 41167
diff changeset
   394
48237
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   395
fun maybe_instantiate_inducts ctxt hyp_ts concl_t =
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   396
  if Config.get ctxt instantiate_inducts then
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   397
    let
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   398
      val thy = Proof_Context.theory_of ctxt
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   399
      val ind_stmt =
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   400
        (hyp_ts |> filter_out (null o external_frees), concl_t)
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   401
        |> Logic.list_implies |> Object_Logic.atomize_term thy
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   402
      val ind_stmt_xs = external_frees ind_stmt
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   403
    in maps (instantiate_if_induct_rule ctxt ind_stmt ind_stmt_xs) end
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   404
  else
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   405
    I
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   406
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   407
fun maybe_filter_no_atps ctxt =
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   408
  not (Config.get ctxt ignore_no_atp) ? filter_out (No_ATPs.member ctxt o snd)
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   409
44585
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   410
fun nearly_all_facts ctxt ho_atp ({add, only, ...} : relevance_override)
cfe7f4a68e51 added generation of induction rules
nik
parents: 44462
diff changeset
   411
                     chained_ths hyp_ts concl_t =
46734
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   412
  if only andalso null add then
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   413
    []
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   414
  else
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   415
    let
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   416
      val reserved = reserved_isar_keyword_table ()
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   417
      val add_ths = Attrib.eval_thms ctxt add
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   418
      val css_table = clasimpset_rule_table_of ctxt
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   419
    in
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   420
      (if only then
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   421
         maps (map (fn ((name, stature), th) => ((K name, stature), th))
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   422
               o fact_from_ref ctxt reserved chained_ths css_table) add
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   423
       else
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   424
         all_facts ctxt ho_atp reserved false add_ths chained_ths css_table)
48237
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   425
      |> maybe_instantiate_inducts ctxt hyp_ts concl_t
d7ad89f60768 export useful functions
blanchet
parents: 48227
diff changeset
   426
      |> not only ? maybe_filter_no_atps ctxt
46734
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   427
      |> uniquify
6256e064f8fa speed up Sledgehammer's clasimpset lookup a bit
blanchet
parents: 46438
diff changeset
   428
    end
43351
b19d95b4d736 compute the set of base facts only once (instead of three times in parallel) -- this saves about .5 s of CPU time, albeit much less clock wall time
blanchet
parents: 43324
diff changeset
   429
48248
b6eb45a52c28 split relevance filter code into three files
blanchet
parents: 48237
diff changeset
   430
val relevant_facts = iterative_relevant_facts
30536
07b4f050e4df split relevance-filter and writing of problem-files;
immler@in.tum.de
parents: 30364
diff changeset
   431
15347
14585bc8fa09 resolution package tools by Jia Meng
paulson
parents:
diff changeset
   432
end;