src/Pure/Thy/thm_deps.ML
changeset 28810 e915ab11fe52
parent 27865 27a8ad9612a3
child 28814 463c9e9111ae
equal deleted inserted replaced
28809:7c2e1bbf3c36 28810:e915ab11fe52
     5 Visualize dependencies of theorems.
     5 Visualize dependencies of theorems.
     6 *)
     6 *)
     7 
     7 
     8 signature THM_DEPS =
     8 signature THM_DEPS =
     9 sig
     9 sig
    10   val enable: unit -> unit
       
    11   val disable: unit -> unit
       
    12   val thm_deps: thm list -> unit
    10   val thm_deps: thm list -> unit
    13   val unused_thms: theory list * theory list -> (string * thm) list
    11   val unused_thms: theory list * theory list -> (string * thm) list
    14 end;
    12 end;
    15 
    13 
    16 structure ThmDeps: THM_DEPS =
    14 structure ThmDeps: THM_DEPS =
    17 struct
    15 struct
    18 
    16 
    19 (* thm_deps *)
    17 (* thm_deps *)
    20 
    18 
    21 fun enable () = CRITICAL (fn () => if ! proofs = 0 then proofs := 1 else ());
    19 fun add_dep ((name, _, _), PBody {thms = thms', ...}) =
    22 fun disable () = proofs := 0;
    20   name <> "" ?
    23 
    21     Graph.new_node (name, ()) #>
    24 local
    22     fold (fn (_, ((name', _, _), _)) => name <> "" ? Graph.add_edge (name', name)) thms';
    25 
       
    26 open Proofterm;
       
    27 
       
    28 fun dest_thm_axm (PThm (name, prf, _, _)) = (name, prf)
       
    29   | dest_thm_axm (PAxm (name, _, _)) = (name ^ " (Ax)", MinProof ([], [], []))
       
    30   | dest_thm_axm _ = ("", MinProof ([], [], []));
       
    31 
       
    32 fun make_deps_graph (AbsP (_, _, prf)) = make_deps_graph prf
       
    33   | make_deps_graph (Abst (_, _, prf)) = make_deps_graph prf
       
    34   | make_deps_graph (prf1 %% prf2) = make_deps_graph prf1 #> make_deps_graph prf2
       
    35   | make_deps_graph (prf % _) = make_deps_graph prf
       
    36   | make_deps_graph (MinProof (thms, axms, _)) =
       
    37       fold (make_deps_graph o Proofterm.proof_of_min_thm) thms #>
       
    38       fold (make_deps_graph o Proofterm.proof_of_min_axm) axms
       
    39   | make_deps_graph prf = (fn p as (gra, parents) =>
       
    40       let val (name, prf') = dest_thm_axm prf
       
    41       in
       
    42         if name <> "" then
       
    43           if not (Symtab.defined gra name) then
       
    44             let
       
    45               val (gra', parents') = make_deps_graph prf' (gra, []);
       
    46               val prefx = #1 (Library.split_last (NameSpace.explode name));
       
    47               val session =
       
    48                 (case prefx of
       
    49                   (x :: _) =>
       
    50                     (case ThyInfo.lookup_theory x of
       
    51                       SOME thy =>
       
    52                         let val name = Present.session_name thy
       
    53                         in if name = "" then [] else [name] end
       
    54                     | NONE => [])
       
    55                  | _ => ["global"]);
       
    56             in
       
    57               if member (op =) parents' name then (gra', parents union parents')
       
    58               else (Symtab.update (name,
       
    59                 {name = Sign.base_name name, ID = name,
       
    60                  dir = space_implode "/" (session @ prefx),
       
    61                  unfold = false, path = "", parents = parents'}) gra',
       
    62                insert (op =) name parents)
       
    63             end
       
    64           else (gra, insert (op =) name parents)
       
    65         else
       
    66           make_deps_graph prf' (gra, parents)
       
    67       end);
       
    68 
       
    69 in
       
    70 
    23 
    71 fun thm_deps thms =
    24 fun thm_deps thms =
    72   Present.display_graph
    25   let
    73     (map snd (sort_wrt fst (Symtab.dest (fst
    26     val graph = Proofterm.fold_body_thms add_dep (map Thm.proof_of thms) Graph.empty;
    74       (fold make_deps_graph (map Thm.proof_of thms) (Symtab.empty, []))))));
    27     fun add_entry (name, (_, (preds, _))) =
    75 
    28       let
    76 end;
    29         val prefix = #1 (Library.split_last (NameSpace.explode name));
       
    30         val session =
       
    31           (case prefix of
       
    32             a :: _ =>
       
    33               (case ThyInfo.lookup_theory a of
       
    34                 SOME thy =>
       
    35                   (case Present.session_name thy of
       
    36                     "" => []
       
    37                   | session => [session])
       
    38               | NONE => [])
       
    39            | _ => ["global"]);
       
    40         val entry =
       
    41           {name = Sign.base_name name,
       
    42            ID = name,
       
    43            dir = space_implode "/" (session @ prefix),
       
    44            unfold = false,
       
    45            path = "",
       
    46            parents = preds};
       
    47       in cons entry end;
       
    48   in Present.display_graph (sort_wrt #ID (Graph.fold add_entry graph [])) end;
    77 
    49 
    78 
    50 
    79 (* unused_thms *)
    51 (* unused_thms *)
    80 
    52 
    81 fun unused_thms (base_thys, thys) =
    53 fun unused_thms (base_thys, thys) =
    84       if exists (fn thy => PureThy.defined_fact thy name) base_thys then I
    56       if exists (fn thy => PureThy.defined_fact thy name) base_thys then I
    85       else fold_rev (fn th => (case Thm.get_name th of "" => I | a => cons (a, th))) ths;
    57       else fold_rev (fn th => (case Thm.get_name th of "" => I | a => cons (a, th))) ths;
    86     val thms =
    58     val thms =
    87       fold (Facts.fold_static add_fact o PureThy.facts_of) thys []
    59       fold (Facts.fold_static add_fact o PureThy.facts_of) thys []
    88       |> sort_distinct (string_ord o pairself #1);
    60       |> sort_distinct (string_ord o pairself #1);
    89     val tab = fold Proofterm.thms_of_proof
    61 
       
    62     val tab = Proofterm.fold_body_thms
       
    63       (fn ((name, prop, _), _) => name <> "" ? Symtab.insert_list (op =) (name, prop))
    90       (map (Proofterm.strip_thm o Thm.proof_of o snd) thms) Symtab.empty;
    64       (map (Proofterm.strip_thm o Thm.proof_of o snd) thms) Symtab.empty;
    91     fun is_unused (name, th) = case Symtab.lookup tab name of
    65     fun is_unused (name, th) =
    92         NONE => true
    66       not (member (op aconv) (Symtab.lookup_list tab name) (Thm.prop_of th));
    93       | SOME ps => not (member (op aconv) (map fst ps) (Thm.prop_of th));
    67 
    94     (* groups containing at least one used theorem *)
    68     (* groups containing at least one used theorem *)
    95     val grps = fold (fn p as (_, thm) => if is_unused p then I else
    69     val grps = fold (fn p as (_, thm) => if is_unused p then I else
    96       case Thm.get_group thm of
    70       case Thm.get_group thm of
    97         NONE => I | SOME grp => Symtab.update (grp, ())) thms Symtab.empty;
    71         NONE => I | SOME grp => Symtab.update (grp, ())) thms Symtab.empty;
    98     val (thms', _) = fold (fn p as (s, thm) => fn q as (thms, grps') =>
    72     val (thms', _) = fold (fn p as (s, thm) => fn q as (thms, grps') =>