src/Pure/General/graph.ML
changeset 19580 c878a09fb849
parent 19482 9f11af8f7ef9
child 19615 e3ab6cd838a4
equal deleted inserted replaced
19579:b802d1804b77 19580:c878a09fb849
    28   val imm_succs: 'a T -> key -> key list
    28   val imm_succs: 'a T -> key -> key list
    29   val all_preds: 'a T -> key list -> key list
    29   val all_preds: 'a T -> key list -> key list
    30   val all_succs: 'a T -> key list -> key list
    30   val all_succs: 'a T -> key list -> key list
    31   val strong_conn: 'a T -> key list list
    31   val strong_conn: 'a T -> key list list
    32   val subgraph: key list -> 'a T -> 'a T
    32   val subgraph: key list -> 'a T -> 'a T
    33   val find_paths: 'a T -> key * key -> key list list
       
    34   val new_node: key * 'a -> 'a T -> 'a T                              (*exception DUP*)
    33   val new_node: key * 'a -> 'a T -> 'a T                              (*exception DUP*)
    35   val default_node: key * 'a -> 'a T -> 'a T
    34   val default_node: key * 'a -> 'a T -> 'a T
    36   val del_nodes: key list -> 'a T -> 'a T                             (*exception UNDEF*)
    35   val del_nodes: key list -> 'a T -> 'a T                             (*exception UNDEF*)
    37   val is_edge: 'a T -> key * key -> bool
    36   val is_edge: 'a T -> key * key -> bool
    38   val add_edge: key * key -> 'a T -> 'a T
    37   val add_edge: key * key -> 'a T -> 'a T
    39   val del_edge: key * key -> 'a T -> 'a T
    38   val del_edge: key * key -> 'a T -> 'a T
    40   val merge: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T                 (*exception DUPS*)
    39   val merge: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T                 (*exception DUPS*)
    41   val join: (key -> 'a * 'a -> 'a) (*exception DUP/SAME*) ->
    40   val join: (key -> 'a * 'a -> 'a) (*exception DUP/SAME*) ->
    42     'a T * 'a T -> 'a T                                               (*exception DUPS*)
    41     'a T * 'a T -> 'a T                                               (*exception DUPS*)
       
    42   val irreducible_paths: 'a T -> key * key -> key list list
    43   exception CYCLES of key list list
    43   exception CYCLES of key list list
    44   val add_edge_acyclic: key * key -> 'a T -> 'a T                     (*exception CYCLES*)
    44   val add_edge_acyclic: key * key -> 'a T -> 'a T                     (*exception CYCLES*)
    45   val add_deps_acyclic: key * key list -> 'a T -> 'a T                (*exception CYCLES*)
    45   val add_deps_acyclic: key * key list -> 'a T -> 'a T                (*exception CYCLES*)
    46   val merge_acyclic: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T         (*exception CYCLES*)
    46   val merge_acyclic: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T         (*exception CYCLES*)
    47   val add_edge_trans_acyclic: key * key -> 'a T -> 'a T               (*exception CYCLES*)
    47   val add_edge_trans_acyclic: key * key -> 'a T -> 'a T               (*exception CYCLES*)
   147     fun subg (k, (i, (preds, succs))) =
   147     fun subg (k, (i, (preds, succs))) =
   148       K (select k) ? Table.update (k, (i, (filter select preds, filter select succs)));
   148       K (select k) ? Table.update (k, (i, (filter select preds, filter select succs)));
   149   in Table.empty |> Table.fold subg tab |> Graph end;
   149   in Table.empty |> Table.fold subg tab |> Graph end;
   150 
   150 
   151 
   151 
   152 (* paths *)
       
   153 
       
   154 fun find_paths G (x, y) =
       
   155   let
       
   156     val (_, X) = reachable (imm_succs G) [x];
       
   157     fun paths ps p =
       
   158       if not (null ps) andalso eq_key (p, x) then [p :: ps]
       
   159       else if member_keys X p andalso not (member_key ps p)
       
   160       then maps (paths (p :: ps)) (imm_preds G p)
       
   161       else [];
       
   162   in paths [] y end;
       
   163 
       
   164 
       
   165 (* nodes *)
   152 (* nodes *)
   166 
   153 
   167 fun new_node (x, info) (Graph tab) =
   154 fun new_node (x, info) (Graph tab) =
   168   Graph (Table.update_new (x, (info, ([], []))) tab);
   155   Graph (Table.update_new (x, (info, ([], []))) tab);
   169 
   156 
   213   in fold add (edges G2) (Graph (Table.merge eq_node (tab1, Table.map no_edges tab2))) end;
   200   in fold add (edges G2) (Graph (Table.merge eq_node (tab1, Table.map no_edges tab2))) end;
   214 
   201 
   215 fun merge eq GG = gen_merge add_edge eq GG;
   202 fun merge eq GG = gen_merge add_edge eq GG;
   216 
   203 
   217 
   204 
       
   205 (* irreducible paths -- Hasse diagram *)
       
   206 
       
   207 fun irreducible_preds G X path z =
       
   208   let
       
   209     fun red x x' = is_edge G (x, x') andalso not (eq_key (x', z));
       
   210     fun irreds [] xs' = xs'
       
   211       | irreds (x :: xs) xs' =
       
   212           if not (member_keys X x) orelse eq_key (x, z) orelse member_key path x orelse
       
   213             exists (red x) xs orelse exists (red x) xs'
       
   214           then irreds xs xs'
       
   215           else irreds xs (x :: xs');
       
   216   in irreds (imm_preds G z) [] end;
       
   217 
       
   218 fun irreducible_paths G (x, y) =
       
   219   let
       
   220     val (_, X) = reachable (imm_succs G) [x];
       
   221     fun paths path z =
       
   222       if eq_key (x, z) then cons (z :: path)
       
   223       else fold (paths (z :: path)) (irreducible_preds G X path z);
       
   224   in if eq_key (x, y) andalso not (is_edge G (x, x)) then [[]] else paths [] y [] end;
       
   225 
       
   226 
   218 (* maintain acyclic graphs *)
   227 (* maintain acyclic graphs *)
   219 
   228 
   220 exception CYCLES of key list list;
   229 exception CYCLES of key list list;
   221 
   230 
   222 fun add_edge_acyclic (x, y) G =
   231 fun add_edge_acyclic (x, y) G =
   223   if is_edge G (x, y) then G
   232   if is_edge G (x, y) then G
   224   else
   233   else
   225     (case find_paths G (y, x) of
   234     (case irreducible_paths G (y, x) of
   226       [] => add_edge (x, y) G
   235       [] => add_edge (x, y) G
   227     | cycles => raise CYCLES (map (cons x) cycles));
   236     | cycles => raise CYCLES (map (cons x) cycles));
   228 
   237 
   229 fun add_deps_acyclic (y, xs) = fold (fn x => add_edge_acyclic (x, y)) xs;
   238 fun add_deps_acyclic (y, xs) = fold (fn x => add_edge_acyclic (x, y)) xs;
   230 
   239