src/Pure/General/graph.ML
changeset 44338 700008399ee5
parent 44202 44c4ae5c5ce2
child 46611 669601fa1a62
equal deleted inserted replaced
44337:d453faed4815 44338:700008399ee5
     5 *)
     5 *)
     6 
     6 
     7 signature GRAPH =
     7 signature GRAPH =
     8 sig
     8 sig
     9   type key
     9   type key
       
    10   structure Keys:
       
    11   sig
       
    12     type T
       
    13     val is_empty: T -> bool
       
    14     val fold: (key -> 'a -> 'a) -> T -> 'a -> 'a
       
    15     val fold_rev: (key -> 'a -> 'a) -> T -> 'a -> 'a
       
    16     val dest: T -> key list
       
    17   end
    10   type 'a T
    18   type 'a T
    11   exception DUP of key
    19   exception DUP of key
    12   exception SAME
    20   exception SAME
    13   exception UNDEF of key
    21   exception UNDEF of key
    14   val empty: 'a T
    22   val empty: 'a T
    15   val is_empty: 'a T -> bool
    23   val is_empty: 'a T -> bool
    16   val keys: 'a T -> key list
    24   val keys: 'a T -> key list
    17   val dest: 'a T -> (key * key list) list
    25   val dest: 'a T -> (key * key list) list
    18   val get_first: (key * ('a * (key list * key list)) -> 'b option) -> 'a T -> 'b option
    26   val get_first: (key * ('a * (Keys.T * Keys.T)) -> 'b option) -> 'a T -> 'b option
    19   val fold: (key * ('a * (key list * key list)) -> 'b -> 'b) -> 'a T -> 'b -> 'b
    27   val fold: (key * ('a * (Keys.T * Keys.T)) -> 'b -> 'b) -> 'a T -> 'b -> 'b
    20   val minimals: 'a T -> key list
       
    21   val maximals: 'a T -> key list
       
    22   val subgraph: (key -> bool) -> 'a T -> 'a T
    28   val subgraph: (key -> bool) -> 'a T -> 'a T
    23   val get_entry: 'a T -> key -> key * ('a * (key list * key list))    (*exception UNDEF*)
    29   val get_entry: 'a T -> key -> key * ('a * (Keys.T * Keys.T))        (*exception UNDEF*)
    24   val map: (key -> 'a -> 'b) -> 'a T -> 'b T
    30   val map: (key -> 'a -> 'b) -> 'a T -> 'b T
    25   val get_node: 'a T -> key -> 'a                                     (*exception UNDEF*)
    31   val get_node: 'a T -> key -> 'a                                     (*exception UNDEF*)
    26   val map_node: key -> ('a -> 'a) -> 'a T -> 'a T
    32   val map_node: key -> ('a -> 'a) -> 'a T -> 'a T
    27   val map_node_yield: key -> ('a -> 'b * 'a) -> 'a T -> 'b * 'a T
    33   val map_node_yield: key -> ('a -> 'b * 'a) -> 'a T -> 'b * 'a T
    28   val imm_preds: 'a T -> key -> key list
    34   val imm_preds: 'a T -> key -> Keys.T
    29   val imm_succs: 'a T -> key -> key list
    35   val imm_succs: 'a T -> key -> Keys.T
       
    36   val immediate_preds: 'a T -> key -> key list
       
    37   val immediate_succs: 'a T -> key -> key list
    30   val all_preds: 'a T -> key list -> key list
    38   val all_preds: 'a T -> key list -> key list
    31   val all_succs: 'a T -> key list -> key list
    39   val all_succs: 'a T -> key list -> key list
       
    40   val minimals: 'a T -> key list
       
    41   val maximals: 'a T -> key list
       
    42   val is_minimal: 'a T -> key -> bool
       
    43   val is_maximal: 'a T -> key -> bool
    32   val strong_conn: 'a T -> key list list
    44   val strong_conn: 'a T -> key list list
    33   val new_node: key * 'a -> 'a T -> 'a T                              (*exception DUP*)
    45   val new_node: key * 'a -> 'a T -> 'a T                              (*exception DUP*)
    34   val default_node: key * 'a -> 'a T -> 'a T
    46   val default_node: key * 'a -> 'a T -> 'a T
    35   val del_nodes: key list -> 'a T -> 'a T                             (*exception UNDEF*)
    47   val del_nodes: key list -> 'a T -> 'a T                             (*exception UNDEF*)
    36   val del_node: key -> 'a T -> 'a T                                   (*exception UNDEF*)
    48   val del_node: key -> 'a T -> 'a T                                   (*exception UNDEF*)
    57 struct
    69 struct
    58 
    70 
    59 (* keys *)
    71 (* keys *)
    60 
    72 
    61 type key = Key.key;
    73 type key = Key.key;
    62 
       
    63 val eq_key = is_equal o Key.ord;
    74 val eq_key = is_equal o Key.ord;
    64 
    75 
    65 val member_key = member eq_key;
       
    66 val remove_key = remove eq_key;
       
    67 
       
    68 
       
    69 (* tables and sets of keys *)
       
    70 
       
    71 structure Table = Table(Key);
    76 structure Table = Table(Key);
    72 type keys = unit Table.table;
    77 
    73 
    78 structure Keys =
    74 val empty_keys = Table.empty: keys;
    79 struct
    75 
    80 
    76 fun member_keys tab = Table.defined (tab: keys);
    81 abstype T = Keys of unit Table.table
    77 fun insert_keys x tab = Table.insert (K true) (x, ()) (tab: keys);
    82 with
       
    83 
       
    84 val empty = Keys Table.empty;
       
    85 fun is_empty (Keys tab) = Table.is_empty tab;
       
    86 
       
    87 fun member (Keys tab) = Table.defined tab;
       
    88 fun insert x (Keys tab) = Keys (Table.insert (K true) (x, ()) tab);
       
    89 fun remove x (Keys tab) = Keys (Table.delete_safe x tab);
       
    90 
       
    91 fun fold f (Keys tab) = Table.fold (f o #1) tab;
       
    92 fun fold_rev f (Keys tab) = Table.fold_rev (f o #1) tab;
       
    93 
       
    94 fun make xs = Basics.fold insert xs empty;
       
    95 fun dest keys = fold_rev cons keys [];
       
    96 
       
    97 fun filter P keys = fold (fn x => P x ? insert x) keys empty;
       
    98 
       
    99 end;
       
   100 end;
    78 
   101 
    79 
   102 
    80 (* graphs *)
   103 (* graphs *)
    81 
   104 
    82 datatype 'a T = Graph of ('a * (key list * key list)) Table.table;
   105 datatype 'a T = Graph of ('a * (Keys.T * Keys.T)) Table.table;
    83 
   106 
    84 exception DUP = Table.DUP;
   107 exception DUP = Table.DUP;
    85 exception UNDEF = Table.UNDEF;
   108 exception UNDEF = Table.UNDEF;
    86 exception SAME = Table.SAME;
   109 exception SAME = Table.SAME;
    87 
   110 
    88 val empty = Graph Table.empty;
   111 val empty = Graph Table.empty;
    89 fun is_empty (Graph tab) = Table.is_empty tab;
   112 fun is_empty (Graph tab) = Table.is_empty tab;
    90 fun keys (Graph tab) = Table.keys tab;
   113 fun keys (Graph tab) = Table.keys tab;
    91 fun dest (Graph tab) = map (fn (x, (_, (_, succs))) => (x, succs)) (Table.dest tab);
   114 fun dest (Graph tab) = map (fn (x, (_, (_, succs))) => (x, Keys.dest succs)) (Table.dest tab);
    92 
   115 
    93 fun get_first f (Graph tab) = Table.get_first f tab;
   116 fun get_first f (Graph tab) = Table.get_first f tab;
    94 fun fold_graph f (Graph tab) = Table.fold f tab;
   117 fun fold_graph f (Graph tab) = Table.fold f tab;
    95 
   118 
    96 fun minimals G = fold_graph (fn (m, (_, ([], _))) => cons m | _ => I) G [];
       
    97 fun maximals G = fold_graph (fn (m, (_, (_, []))) => cons m | _ => I) G [];
       
    98 
       
    99 fun subgraph P G =
   119 fun subgraph P G =
   100   let
   120   let
   101     fun subg (k, (i, (preds, succs))) =
   121     fun subg (k, (i, (preds, succs))) =
   102       if P k then Table.update (k, (i, (filter P preds, filter P succs))) else I;
   122       if P k then Table.update (k, (i, (Keys.filter P preds, Keys.filter P succs)))
       
   123       else I;
   103   in Graph (fold_graph subg G Table.empty) end;
   124   in Graph (fold_graph subg G Table.empty) end;
   104 
   125 
   105 fun get_entry (Graph tab) x =
   126 fun get_entry (Graph tab) x =
   106   (case Table.lookup_key tab x of
   127   (case Table.lookup_key tab x of
   107     SOME entry => entry
   128     SOME entry => entry
   130 
   151 
   131 (*nodes reachable from xs -- topologically sorted for acyclic graphs*)
   152 (*nodes reachable from xs -- topologically sorted for acyclic graphs*)
   132 fun reachable next xs =
   153 fun reachable next xs =
   133   let
   154   let
   134     fun reach x (rs, R) =
   155     fun reach x (rs, R) =
   135       if member_keys R x then (rs, R)
   156       if Keys.member R x then (rs, R)
   136       else fold reach (next x) (rs, insert_keys x R) |>> cons x;
   157       else Keys.fold reach (next x) (rs, Keys.insert x R) |>> cons x;
   137     fun reachs x (rss, R) =
   158     fun reachs x (rss, R) =
   138       reach x ([], R) |>> (fn rs => rs :: rss);
   159       reach x ([], R) |>> (fn rs => rs :: rss);
   139   in fold reachs xs ([], empty_keys) end;
   160   in fold reachs xs ([], Keys.empty) end;
   140 
   161 
   141 (*immediate*)
   162 (*immediate*)
   142 fun imm_preds G = #1 o #2 o #2 o get_entry G;
   163 fun imm_preds G = #1 o #2 o #2 o get_entry G;
   143 fun imm_succs G = #2 o #2 o #2 o get_entry G;
   164 fun imm_succs G = #2 o #2 o #2 o get_entry G;
   144 
   165 
       
   166 fun immediate_preds G = Keys.dest o imm_preds G;
       
   167 fun immediate_succs G = Keys.dest o imm_succs G;
       
   168 
   145 (*transitive*)
   169 (*transitive*)
   146 fun all_preds G = flat o #1 o reachable (imm_preds G);
   170 fun all_preds G = flat o #1 o reachable (imm_preds G);
   147 fun all_succs G = flat o #1 o reachable (imm_succs G);
   171 fun all_succs G = flat o #1 o reachable (imm_succs G);
       
   172 
       
   173 (*minimal and maximal elements*)
       
   174 fun minimals G = fold_graph (fn (m, (_, (preds, _))) => Keys.is_empty preds ? cons m) G [];
       
   175 fun maximals G = fold_graph (fn (m, (_, (_, succs))) => Keys.is_empty succs ? cons m) G [];
       
   176 fun is_minimal G x = Keys.is_empty (imm_preds G x);
       
   177 fun is_maximal G x = Keys.is_empty (imm_succs G x);
   148 
   178 
   149 (*strongly connected components; see: David King and John Launchbury,
   179 (*strongly connected components; see: David King and John Launchbury,
   150   "Structuring Depth First Search Algorithms in Haskell"*)
   180   "Structuring Depth First Search Algorithms in Haskell"*)
   151 fun strong_conn G =
   181 fun strong_conn G =
   152   rev (filter_out null (#1 (reachable (imm_preds G) (all_succs G (keys G)))));
   182   rev (filter_out null (#1 (reachable (imm_preds G) (all_succs G (keys G)))));
   153 
   183 
   154 
   184 
   155 (* nodes *)
   185 (* nodes *)
   156 
   186 
   157 fun new_node (x, info) (Graph tab) =
   187 fun new_node (x, info) (Graph tab) =
   158   Graph (Table.update_new (x, (info, ([], []))) tab);
   188   Graph (Table.update_new (x, (info, (Keys.empty, Keys.empty))) tab);
   159 
   189 
   160 fun default_node (x, info) (Graph tab) =
   190 fun default_node (x, info) (Graph tab) =
   161   Graph (Table.default (x, (info, ([], []))) tab);
   191   Graph (Table.default (x, (info, (Keys.empty, Keys.empty))) tab);
   162 
   192 
   163 fun del_nodes xs (Graph tab) =
   193 fun del_nodes xs (Graph tab) =
   164   Graph (tab
   194   Graph (tab
   165     |> fold Table.delete xs
   195     |> fold Table.delete xs
   166     |> Table.map (fn _ => fn (i, (preds, succs)) =>
   196     |> Table.map (fn _ => fn (i, (preds, succs)) =>
   167       (i, (fold remove_key xs preds, fold remove_key xs succs))));
   197       (i, (fold Keys.remove xs preds, fold Keys.remove xs succs))));
   168 
   198 
   169 fun del_node x (G as Graph tab) =
   199 fun del_node x (G as Graph tab) =
   170   let
   200   let
   171     fun del_adjacent which y = Table.map_entry y (fn (i, ps) => (i, (which (remove_key x) ps)));
   201     fun del_adjacent which y =
       
   202       Table.map_entry y (fn (i, ps) => (i, (which (Keys.remove x) ps)));
   172     val (preds, succs) = #2 (#2 (get_entry G x));
   203     val (preds, succs) = #2 (#2 (get_entry G x));
   173   in
   204   in
   174     Graph (tab
   205     Graph (tab
   175       |> Table.delete x
   206       |> Table.delete x
   176       |> fold (del_adjacent apsnd) preds
   207       |> Keys.fold (del_adjacent apsnd) preds
   177       |> fold (del_adjacent apfst) succs)
   208       |> Keys.fold (del_adjacent apfst) succs)
   178   end;
   209   end;
   179 
   210 
   180 
   211 
   181 (* edges *)
   212 (* edges *)
   182 
   213 
   183 fun is_edge G (x, y) = member_key (imm_succs G x) y handle UNDEF _ => false;
   214 fun is_edge G (x, y) = Keys.member (imm_succs G x) y handle UNDEF _ => false;
   184 
   215 
   185 fun add_edge (x, y) G =
   216 fun add_edge (x, y) G =
   186   if is_edge G (x, y) then G
   217   if is_edge G (x, y) then G
   187   else
   218   else
   188     G |> map_entry y (fn (i, (preds, succs)) => (i, (x :: preds, succs)))
   219     G |> map_entry y (fn (i, (preds, succs)) => (i, (Keys.insert x preds, succs)))
   189       |> map_entry x (fn (i, (preds, succs)) => (i, (preds, y :: succs)));
   220       |> map_entry x (fn (i, (preds, succs)) => (i, (preds, Keys.insert y succs)));
   190 
   221 
   191 fun del_edge (x, y) G =
   222 fun del_edge (x, y) G =
   192   if is_edge G (x, y) then
   223   if is_edge G (x, y) then
   193     G |> map_entry y (fn (i, (preds, succs)) => (i, (remove_key x preds, succs)))
   224     G |> map_entry y (fn (i, (preds, succs)) => (i, (Keys.remove x preds, succs)))
   194       |> map_entry x (fn (i, (preds, succs)) => (i, (preds, remove_key y succs)))
   225       |> map_entry x (fn (i, (preds, succs)) => (i, (preds, Keys.remove y succs)))
   195   else G;
   226   else G;
   196 
   227 
   197 fun diff_edges G1 G2 =
   228 fun diff_edges G1 G2 =
   198   flat (dest G1 |> map (fn (x, ys) => ys |> map_filter (fn y =>
   229   flat (dest G1 |> map (fn (x, ys) => ys |> map_filter (fn y =>
   199     if is_edge G2 (x, y) then NONE else SOME (x, y))));
   230     if is_edge G2 (x, y) then NONE else SOME (x, y))));
   201 fun edges G = diff_edges G empty;
   232 fun edges G = diff_edges G empty;
   202 
   233 
   203 
   234 
   204 (* join and merge *)
   235 (* join and merge *)
   205 
   236 
   206 fun no_edges (i, _) = (i, ([], []));
   237 fun no_edges (i, _) = (i, (Keys.empty, Keys.empty));
   207 
   238 
   208 fun join f (G1 as Graph tab1, G2 as Graph tab2) =
   239 fun join f (G1 as Graph tab1, G2 as Graph tab2) =
   209   let fun join_node key ((i1, edges1), (i2, _)) = (f key (i1, i2), edges1) in
   240   let fun join_node key ((i1, edges1), (i2, _)) = (f key (i1, i2), edges1) in
   210     if pointer_eq (G1, G2) then G1
   241     if pointer_eq (G1, G2) then G1
   211     else fold add_edge (edges G2) (Graph (Table.join join_node (tab1, Table.map (K no_edges) tab2)))
   242     else fold add_edge (edges G2) (Graph (Table.join join_node (tab1, Table.map (K no_edges) tab2)))
   225 fun irreducible_preds G X path z =
   256 fun irreducible_preds G X path z =
   226   let
   257   let
   227     fun red x x' = is_edge G (x, x') andalso not (eq_key (x', z));
   258     fun red x x' = is_edge G (x, x') andalso not (eq_key (x', z));
   228     fun irreds [] xs' = xs'
   259     fun irreds [] xs' = xs'
   229       | irreds (x :: xs) xs' =
   260       | irreds (x :: xs) xs' =
   230           if not (member_keys X x) orelse eq_key (x, z) orelse member_key path x orelse
   261           if not (Keys.member X x) orelse eq_key (x, z) orelse member eq_key path x orelse
   231             exists (red x) xs orelse exists (red x) xs'
   262             exists (red x) xs orelse exists (red x) xs'
   232           then irreds xs xs'
   263           then irreds xs xs'
   233           else irreds xs (x :: xs');
   264           else irreds xs (x :: xs');
   234   in irreds (imm_preds G z) [] end;
   265   in irreds (immediate_preds G z) [] end;
   235 
   266 
   236 fun irreducible_paths G (x, y) =
   267 fun irreducible_paths G (x, y) =
   237   let
   268   let
   238     val (_, X) = reachable (imm_succs G) [x];
   269     val (_, X) = reachable (imm_succs G) [x];
   239     fun paths path z =
   270     fun paths path z =
   247 fun all_paths G (x, y) =
   278 fun all_paths G (x, y) =
   248   let
   279   let
   249     val (_, X) = reachable (imm_succs G) [x];
   280     val (_, X) = reachable (imm_succs G) [x];
   250     fun paths path z =
   281     fun paths path z =
   251       if not (null path) andalso eq_key (x, z) then [z :: path]
   282       if not (null path) andalso eq_key (x, z) then [z :: path]
   252       else if member_keys X z andalso not (member_key path z)
   283       else if Keys.member X z andalso not (member eq_key path z)
   253       then maps (paths (z :: path)) (imm_preds G z)
   284       then maps (paths (z :: path)) (immediate_preds G z)
   254       else [];
   285       else [];
   255   in paths [] y end;
   286   in paths [] y end;
   256 
   287 
   257 
   288 
   258 (* maintain acyclic graphs *)
   289 (* maintain acyclic graphs *)
   295   let
   326   let
   296     val xs = topological_order G;
   327     val xs = topological_order G;
   297     val results = (xs, Table.empty) |-> fold (fn x => fn tab =>
   328     val results = (xs, Table.empty) |-> fold (fn x => fn tab =>
   298       let
   329       let
   299         val a = get_node G x;
   330         val a = get_node G x;
   300         val deps = imm_preds G x |> map (fn y =>
   331         val deps = immediate_preds G x |> map (fn y =>
   301           (case Table.lookup tab y of
   332           (case Table.lookup tab y of
   302             SOME b => (y, b)
   333             SOME b => (y, b)
   303           | NONE => raise DEP (x, y)));
   334           | NONE => raise DEP (x, y)));
   304       in Table.update (x, f deps (x, a)) tab end);
   335       in Table.update (x, f deps (x, a)) tab end);
   305   in map (the o Table.lookup results) xs end;
   336   in map (the o Table.lookup results) xs end;