src/Pure/Tools/find_consts.ML
author wenzelm
Fri, 27 Feb 2009 15:46:22 +0100
changeset 30142 8d6145694bb5
parent 29895 src/Pure/Isar/find_consts.ML@0e70a29d3e02
child 30143 98a986b02022
permissions -rw-r--r--
moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
29884
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
     1
(*  Title:      find_consts.ML
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
     2
    Author:     Timothy Bourke and Gerwin Klein, NICTA
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
     3
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
     4
  Hoogle-like (http://www-users.cs.york.ac.uk/~ndm/hoogle) searching by type
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
     5
  over constants, but matching is not fuzzy
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
     6
*)
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
     7
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
     8
signature FIND_CONSTS =
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
     9
sig
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    10
  datatype criterion = Strict of string
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    11
                     | Loose of string
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    12
                     | Name of string
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    13
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    14
  val default_criteria : (bool * criterion) list ref
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    15
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    16
  val find_consts : Proof.context -> (bool * criterion) list -> unit
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    17
end;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    18
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    19
structure FindConsts : FIND_CONSTS =
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    20
struct
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    21
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    22
datatype criterion = Strict of string
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    23
                   | Loose of string
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    24
                   | Name of string;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    25
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    26
val default_criteria = ref [(false, Name ".sko_")];
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    27
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    28
fun add_tye (_, (_, t)) n = size_of_typ t + n;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    29
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    30
fun matches_subtype thy typat = let
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    31
    val p = can (fn ty => Sign.typ_match thy (typat, ty) Vartab.empty);
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    32
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    33
    fun fs [] = false
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    34
      | fs (t::ts) = f t orelse fs ts
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    35
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    36
    and f (t as Type (_, ars)) = p t orelse fs ars
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    37
      | f t = p t;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    38
  in f end;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    39
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    40
fun check_const p (nm, (ty, _)) = if p (nm, ty)
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    41
                                  then SOME (size_of_typ ty)
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    42
                                  else NONE;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    43
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    44
fun opt_not f (c as (_, (ty, _))) = if is_some (f c)
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    45
                                    then NONE else SOME (size_of_typ ty);
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    46
29895
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    47
fun filter_const (_, NONE) = NONE
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    48
  | filter_const (f, (SOME (c, r))) = Option.map
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    49
                                        (pair c o ((curry Int.min) r)) (f c);
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    50
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    51
fun pretty_criterion (b, c) =
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    52
  let
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    53
    fun prfx s = if b then s else "-" ^ s;
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    54
  in
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    55
    (case c of
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    56
      Strict pat => Pretty.str (prfx "strict: " ^ quote pat)
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    57
    | Loose pat => Pretty.str (prfx (quote pat))
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    58
    | Name name => Pretty.str (prfx "name: " ^ quote name))
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    59
  end;
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    60
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    61
fun pretty_const ctxt (nm, ty) = let
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    62
    val ty' = Logic.unvarifyT ty;
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    63
  in
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    64
    Pretty.block [Pretty.quote (Pretty.str nm), Pretty.fbrk,
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    65
                  Pretty.str "::", Pretty.brk 1,
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    66
                  Pretty.quote (Syntax.pretty_typ ctxt ty')]
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    67
  end;
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    68
29884
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    69
fun find_consts ctxt raw_criteria = let
29895
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    70
    val start = start_timing ();
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    71
29884
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    72
    val thy = ProofContext.theory_of ctxt;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    73
    val low_ranking = 10000;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    74
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    75
    fun make_pattern crit = ProofContext.read_term_pattern ctxt ("_::" ^ crit)
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    76
                            |> type_of;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    77
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    78
    fun make_match (Strict arg) =
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    79
          let val qty = make_pattern arg; in
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    80
            fn (_, (ty, _)) => let
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    81
                val tye = Sign.typ_match thy (qty, ty) Vartab.empty;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    82
                val sub_size = Vartab.fold add_tye tye 0;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    83
              in SOME sub_size end handle MATCH => NONE
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    84
          end
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    85
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    86
      | make_match (Loose arg) =
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    87
          check_const (matches_subtype thy (make_pattern arg) o snd)
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    88
      
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    89
      | make_match (Name arg) = check_const (match_string arg o fst);
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    90
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    91
    fun make_criterion (b, crit) = (if b then I else opt_not) (make_match crit);
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    92
    val criteria = map make_criterion ((!default_criteria) @ raw_criteria);
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    93
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    94
    val (_, consts) = (#constants o Consts.dest o Sign.consts_of) thy;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    95
    fun eval_entry c = foldl filter_const (SOME (c, low_ranking)) criteria;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
    96
29895
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    97
    val matches = Symtab.fold (cons o eval_entry) consts []
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    98
                  |> map_filter I
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
    99
                  |> sort (rev_order o int_ord o pairself snd)
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   100
                  |> map ((apsnd fst) o fst);
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   101
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   102
    val end_msg = " in " ^
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   103
                  (List.nth (String.tokens Char.isSpace (end_timing start), 3))
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   104
                  ^ " secs"
29884
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
   105
  in
29895
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   106
    Pretty.big_list "searched for:" (map pretty_criterion raw_criteria)
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   107
      :: Pretty.str ""
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   108
      :: (Pretty.str o concat)
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   109
           (if null matches
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   110
            then ["nothing found", end_msg]
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   111
            else ["found ", (string_of_int o length) matches,
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   112
                  " constants", end_msg, ":"])
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   113
      :: Pretty.str ""
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   114
      :: map (pretty_const ctxt) matches
0e70a29d3e02 find_consts: display the search criteria. (by Timothy Bourke)
kleing
parents: 29884
diff changeset
   115
    |> Pretty.chunks
29884
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
   116
    |> Pretty.writeln
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
   117
  end handle ERROR s => Output.error_msg s
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
   118
30142
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   119
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   120
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   121
(** command syntax **)
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   122
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   123
fun find_consts_cmd spec =
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   124
  Toplevel.unknown_theory o Toplevel.keep (fn state =>
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   125
    find_consts (Proof.context_of (Toplevel.enter_proof_body state)) spec);
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   126
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   127
local
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   128
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   129
structure P = OuterParse and K = OuterKeyword;
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   130
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   131
val criterion =
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   132
  P.reserved "strict" |-- P.!!! (P.$$$ ":" |-- P.xname) >> Strict ||
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   133
  P.reserved "name" |-- P.!!! (P.$$$ ":" |-- P.xname) >> Name ||
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   134
  P.xname >> Loose;
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   135
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   136
in
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   137
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   138
val _ =
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   139
  OuterSyntax.improper_command "find_consts" "search constants by type pattern" K.diag
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   140
    (Scan.repeat (((Scan.option P.minus >> is_none) -- criterion))
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   141
      >> (Toplevel.no_timing oo find_consts_cmd));
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   142
29884
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
   143
end;
74c183927054 added ML file for the find_consts command
kleing
parents:
diff changeset
   144
30142
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   145
end;
8d6145694bb5 moved find_theorems.ML and find_consts.ML to Pure/Tools, collecting main implementation in one place each;
wenzelm
parents: 29895
diff changeset
   146