src/Pure/Tools/find_consts.ML
changeset 31684 d5d830979a54
parent 30207 c56d27155041
child 31687 0d2f700fe5e7
equal deleted inserted replaced
31683:7652c87c2db5 31684:d5d830979a54
    23 datatype criterion =
    23 datatype criterion =
    24     Strict of string
    24     Strict of string
    25   | Loose of string
    25   | Loose of string
    26   | Name of string;
    26   | Name of string;
    27 
    27 
       
    28 
    28 (* matching types/consts *)
    29 (* matching types/consts *)
    29 
       
    30 fun add_tye (_, (_, t)) n = Term.size_of_typ t + n;
       
    31 
    30 
    32 fun matches_subtype thy typat =
    31 fun matches_subtype thy typat =
    33   let
    32   let
    34     val p = can (fn ty => Sign.typ_match thy (typat, ty) Vartab.empty);
    33     val p = can (fn ty => Sign.typ_match thy (typat, ty) Vartab.empty);
    35 
    34 
    49   if is_some (f c)
    48   if is_some (f c)
    50   then NONE else SOME (Term.size_of_typ ty);
    49   then NONE else SOME (Term.size_of_typ ty);
    51 
    50 
    52 fun filter_const _ NONE = NONE
    51 fun filter_const _ NONE = NONE
    53   | filter_const f (SOME (c, r)) =
    52   | filter_const f (SOME (c, r)) =
    54       Option.map (pair c o (curry Int.min r)) (f c);
    53       (case f c of
       
    54         NONE => NONE
       
    55       | SOME i => SOME (c, Int.min (r, i)));
    55 
    56 
    56 
    57 
    57 (* pretty results *)
    58 (* pretty results *)
    58 
    59 
    59 fun pretty_criterion (b, c) =
    60 fun pretty_criterion (b, c) =
    74      [Pretty.quote (Pretty.str nm), Pretty.fbrk,
    75      [Pretty.quote (Pretty.str nm), Pretty.fbrk,
    75       Pretty.str "::", Pretty.brk 1,
    76       Pretty.str "::", Pretty.brk 1,
    76       Pretty.quote (Syntax.pretty_typ ctxt ty')]
    77       Pretty.quote (Syntax.pretty_typ ctxt ty')]
    77   end;
    78   end;
    78 
    79 
       
    80 
    79 (* find_consts *)
    81 (* find_consts *)
    80 
    82 
    81 fun find_consts ctxt raw_criteria =
    83 fun find_consts ctxt raw_criteria =
    82   let
    84   let
    83     val start = start_timing ();
    85     val start = start_timing ();
    84 
    86 
    85     val thy = ProofContext.theory_of ctxt;
    87     val thy = ProofContext.theory_of ctxt;
    86     val low_ranking = 10000;
    88     val low_ranking = 10000;
    87 
    89 
    88     fun not_internal consts (nm, _) = 
    90     fun not_internal consts (nm, _) =
    89       if member (op =) (Consts.the_tags consts nm) Markup.property_internal
    91       if member (op =) (Consts.the_tags consts nm) Markup.property_internal
    90       then NONE else SOME low_ranking;
    92       then NONE else SOME low_ranking;
    91 
    93 
    92     fun make_pattern crit =
    94     fun make_pattern crit =
    93       let
    95       let
    94         val raw_T = Syntax.parse_typ ctxt crit;
    96         val raw_T = Syntax.parse_typ ctxt crit;
    95         val t = Syntax.check_term
    97         val t =
    96                   (ProofContext.set_mode ProofContext.mode_pattern ctxt)
    98           Syntax.check_term
    97                   (Term.dummy_pattern raw_T);
    99             (ProofContext.set_mode ProofContext.mode_pattern ctxt)
       
   100             (Term.dummy_pattern raw_T);
    98       in Term.type_of t end;
   101       in Term.type_of t end;
    99 
   102 
   100     fun make_match (Strict arg) =
   103     fun make_match (Strict arg) =
   101           let val qty = make_pattern arg; in
   104           let val qty = make_pattern arg; in
   102             fn (_, (ty, _)) =>
   105             fn (_, (ty, _)) =>
   103               let
   106               let
   104                 val tye = Sign.typ_match thy (qty, ty) Vartab.empty;
   107                 val tye = Sign.typ_match thy (qty, ty) Vartab.empty;
   105                 val sub_size = Vartab.fold add_tye tye 0;
   108                 val sub_size =
       
   109                   Vartab.fold (fn (_, (_, t)) => fn n => Term.size_of_typ t + n) tye 0;
   106               in SOME sub_size end handle MATCH => NONE
   110               in SOME sub_size end handle MATCH => NONE
   107           end
   111           end
   108 
       
   109       | make_match (Loose arg) =
   112       | make_match (Loose arg) =
   110           check_const (matches_subtype thy (make_pattern arg) o snd)
   113           check_const (matches_subtype thy (make_pattern arg) o snd)
   111       
       
   112       | make_match (Name arg) = check_const (match_string arg o fst);
   114       | make_match (Name arg) = check_const (match_string arg o fst);
   113 
   115 
   114     fun make_criterion (b, crit) = (if b then I else opt_not) (make_match crit);
   116     fun make_criterion (b, crit) = (if b then I else opt_not) (make_match crit);
   115     val criteria = map make_criterion raw_criteria;
   117     val criteria = map make_criterion raw_criteria;
   116 
   118 
   117     val consts = Sign.consts_of thy;
   119     val consts = Sign.consts_of thy;
   118     val (_, consts_tab) = (#constants o Consts.dest) consts;
   120     val (_, consts_tab) = #constants (Consts.dest consts);
   119     fun eval_entry c = fold filter_const (not_internal consts::criteria)
   121     fun eval_entry c =
   120                                          (SOME (c, low_ranking));
   122       fold filter_const (not_internal consts :: criteria)
       
   123         (SOME (c, low_ranking));
   121 
   124 
   122     val matches =
   125     val matches =
   123       Symtab.fold (cons o eval_entry) consts_tab []
   126       Symtab.fold (cons o eval_entry) consts_tab []
   124       |> map_filter I
   127       |> map_filter I
   125       |> sort (rev_order o int_ord o pairself snd)
   128       |> sort (rev_order o int_ord o pairself snd)
   126       |> map ((apsnd fst) o fst);
   129       |> map (apsnd fst o fst);
   127 
   130 
   128     val end_msg = " in " ^ Time.toString (#all (end_timing start)) ^ " secs";
   131     val end_msg = " in " ^ Time.toString (#all (end_timing start)) ^ " secs";
   129   in
   132   in
   130     Pretty.big_list "searched for:" (map pretty_criterion raw_criteria)
   133     Pretty.big_list "searched for:" (map pretty_criterion raw_criteria)
   131       :: Pretty.str ""
   134       :: Pretty.str ""
   132       :: (Pretty.str o concat)
   135       :: (Pretty.str o implode)
   133            (if null matches
   136            (if null matches
   134             then ["nothing found", end_msg]
   137             then ["nothing found", end_msg]
   135             else ["found ", (string_of_int o length) matches,
   138             else ["found ", (string_of_int o length) matches,
   136                   " constants", end_msg, ":"])
   139                   " constants", end_msg, ":"])
   137       :: Pretty.str ""
   140       :: Pretty.str ""