src/Pure/General/graph.ML
changeset 9321 e0dda4bde88c
parent 8806 a202293db3f6
child 9347 1791a62b33e7
equal deleted inserted replaced
9320:803cb9c9d4dd 9321:e0dda4bde88c
     8 
     8 
     9 signature GRAPH =
     9 signature GRAPH =
    10 sig
    10 sig
    11   type key
    11   type key
    12   type 'a T
    12   type 'a T
    13   exception UNDEFINED of key
    13   exception UNDEF of key
       
    14   exception DUP of key
       
    15   exception DUPS of key list
    14   val empty: 'a T
    16   val empty: 'a T
    15   val keys: 'a T -> key list
    17   val keys: 'a T -> key list
    16   val map_nodes: ('a -> 'b) -> 'a T -> 'b T
    18   val map_nodes: ('a -> 'b) -> 'a T -> 'b T
    17   val get_node: 'a T -> key -> 'a
    19   val get_node: 'a T -> key -> 'a
    18   val map_node: key -> ('a -> 'a) -> 'a T -> 'a T
    20   val map_node: key -> ('a -> 'a) -> 'a T -> 'a T
    19   val imm_preds: 'a T -> key -> key list
    21   val imm_preds: 'a T -> key -> key list
    20   val imm_succs: 'a T -> key -> key list
    22   val imm_succs: 'a T -> key -> key list
    21   val all_preds: 'a T -> key list -> key list
    23   val all_preds: 'a T -> key list -> key list
    22   val all_succs: 'a T -> key list -> key list
    24   val all_succs: 'a T -> key list -> key list
    23   val find_paths: 'a T -> key * key -> key list list
    25   val find_paths: 'a T -> key * key -> key list list
    24   exception DUPLICATE of key
       
    25   val new_node: key * 'a -> 'a T -> 'a T
    26   val new_node: key * 'a -> 'a T -> 'a T
    26   val del_nodes: key list -> 'a T -> 'a T
    27   val del_nodes: key list -> 'a T -> 'a T
       
    28   val edges: 'a T -> (key * key) list
    27   val add_edge: key * key -> 'a T -> 'a T
    29   val add_edge: key * key -> 'a T -> 'a T
    28   val del_edge: key * key -> 'a T -> 'a T
    30   val del_edge: key * key -> 'a T -> 'a T
    29   exception CYCLES of key list list
    31   exception CYCLES of key list list
    30   val add_edge_acyclic: key * key -> 'a T -> 'a T
    32   val add_edge_acyclic: key * key -> 'a T -> 'a T
       
    33   val add_deps_acyclic: key * key list -> 'a T -> 'a T
       
    34   val merge_acyclic: ('a * 'a -> bool) -> 'a T * 'a T -> 'a T
    31 end;
    35 end;
    32 
    36 
    33 functor GraphFun(Key: KEY): GRAPH =
    37 functor GraphFun(Key: KEY): GRAPH =
    34 struct
    38 struct
    35 
    39 
    69 
    73 
    70 (* graphs *)
    74 (* graphs *)
    71 
    75 
    72 datatype 'a T = Graph of ('a * (key list * key list)) Table.table;
    76 datatype 'a T = Graph of ('a * (key list * key list)) Table.table;
    73 
    77 
    74 exception UNDEFINED of key;
    78 exception UNDEF of key;
       
    79 exception DUP = Table.DUP;
       
    80 exception DUPS = Table.DUPS;
    75 
    81 
    76 val empty = Graph Table.empty;
    82 val empty = Graph Table.empty;
    77 fun keys (Graph tab) = Table.keys tab;
    83 fun keys (Graph tab) = Table.keys tab;
    78 
    84 
    79 fun get_entry (Graph tab) x =
    85 fun get_entry (Graph tab) x =
    80   (case Table.lookup (tab, x) of
    86   (case Table.lookup (tab, x) of
    81     Some entry => entry
    87     Some entry => entry
    82   | None => raise UNDEFINED x);
    88   | None => raise UNDEF x);
    83 
    89 
    84 fun map_entry x f (G as Graph tab) = Graph (Table.update ((x, f (get_entry G x)), tab));
    90 fun map_entry x f (G as Graph tab) = Graph (Table.update ((x, f (get_entry G x)), tab));
    85 
    91 
    86 
    92 
    87 (* nodes *)
    93 (* nodes *)
   122       else flat (map (paths (p :: ps))
   128       else flat (map (paths (p :: ps))
   123         (filter (fn pp => pp mem_keys X andalso not (pp mem_key ps)) (imm_preds G p)));
   129         (filter (fn pp => pp mem_keys X andalso not (pp mem_key ps)) (imm_preds G p)));
   124   in get_entry G y; if y mem_keys X then (paths [] y) else [] end;
   130   in get_entry G y; if y mem_keys X then (paths [] y) else [] end;
   125 
   131 
   126 
   132 
   127 (* build graphs *)
   133 (* nodes *)
   128 
   134 
   129 exception DUPLICATE of key;
   135 exception DUPLICATE of key;
   130 
   136 
   131 fun new_node (x, info) (Graph tab) =
   137 fun new_node (x, info) (Graph tab) =
   132   Graph (Table.update_new ((x, (info, ([], []))), tab)
   138   Graph (Table.update_new ((x, (info, ([], []))), tab));
   133     handle Table.DUP key => raise DUPLICATE key);
       
   134 
   139 
   135 fun del_nodes xs (Graph tab) =
   140 fun del_nodes xs (Graph tab) =
   136   let
   141   let
   137     fun del (x, (i, (preds, succs))) =
   142     fun del (x, (i, (preds, succs))) =
   138       if x mem_key xs then None
   143       if x mem_key xs then None
   139       else Some (x, (i, (preds del_keys xs, succs del_keys xs)));
   144       else Some (x, (i, (preds del_keys xs, succs del_keys xs)));
   140   in Graph (Table.make (mapfilter del (Table.dest tab))) end;
   145   in Graph (Table.make (mapfilter del (Table.dest tab))) end;
   141 
   146 
       
   147 
       
   148 (* edges *)
       
   149 
       
   150 fun edges (Graph tab) =
       
   151   flat (map (fn (x, (_, (_, succs))) => (map (pair x) succs)) (Table.dest tab));
   142 
   152 
   143 fun add_edge (x, y) =
   153 fun add_edge (x, y) =
   144   map_entry x (fn (i, (preds, succs)) => (i, (preds, y ins_key succs))) o
   154   map_entry x (fn (i, (preds, succs)) => (i, (preds, y ins_key succs))) o
   145    map_entry y (fn (i, (preds, succs)) => (i, (x ins_key preds, succs)));
   155    map_entry y (fn (i, (preds, succs)) => (i, (x ins_key preds, succs)));
   146 
   156 
   154 fun add_edge_acyclic (x, y) G =
   164 fun add_edge_acyclic (x, y) G =
   155   (case find_paths G (y, x) of
   165   (case find_paths G (y, x) of
   156     [] => add_edge (x, y) G
   166     [] => add_edge (x, y) G
   157   | cycles => raise CYCLES (map (cons x) cycles));
   167   | cycles => raise CYCLES (map (cons x) cycles));
   158 
   168 
       
   169 fun add_deps_acyclic (y, xs) G =
       
   170   foldl (fn (H, x) => add_edge_acyclic (x, y) H) (G, xs);
       
   171 
       
   172 
       
   173 (* merge_acyclic *)
       
   174 
       
   175 fun merge_acyclic eq (Graph tab1, G2 as Graph tab2) =
       
   176   foldl (fn (G, xy) => add_edge_acyclic xy G)
       
   177     (Graph (Table.merge (fn ((i1, _), (i2, _)) => eq (i1, i2)) (tab1, tab2)), edges G2);
       
   178 
   159 
   179 
   160 end;
   180 end;
   161 
   181 
   162 
   182 
   163 (*graphs indexed by strings*)
   183 (*graphs indexed by strings*)