src/Pure/General/graph.ML
changeset 6659 7a056250899d
parent 6152 bc1e27bcc195
child 8806 a202293db3f6
equal deleted inserted replaced
6658:b44dd06378cc 6659:7a056250899d
     9 sig
     9 sig
    10   type key
    10   type key
    11   type 'a T
    11   type 'a T
    12   exception UNDEFINED of key
    12   exception UNDEFINED of key
    13   val empty: 'a T
    13   val empty: 'a T
    14   val get_nodes: 'a T -> (key * 'a) list
    14   val keys: 'a T -> key list
    15   val map_nodes: ('a -> 'b) -> 'a T -> 'b T
    15   val map_nodes: ('a -> 'b) -> 'a T -> 'b T
    16   val get_node: 'a T -> key -> 'a
    16   val get_node: 'a T -> key -> 'a
    17   val map_node: key -> ('a -> 'a) -> 'a T -> 'a T
    17   val map_node: key -> ('a -> 'a) -> 'a T -> 'a T
    18   val imm_preds: 'a T -> key -> key list
    18   val imm_preds: 'a T -> key -> key list
    19   val imm_succs: 'a T -> key -> key list
    19   val imm_succs: 'a T -> key -> key list
    20   val all_preds: 'a T -> key list -> key list
    20   val all_preds: 'a T -> key list -> key list
    21   val all_succs: 'a T -> key list -> key list
    21   val all_succs: 'a T -> key list -> key list
    22   val find_paths: 'a T -> key * key -> key list list
    22   val find_paths: 'a T -> key * key -> key list list
    23   exception DUPLICATE of key
    23   exception DUPLICATE of key
    24   val new_node: key * 'a -> 'a T -> 'a T
    24   val new_node: key * 'a -> 'a T -> 'a T
       
    25   val del_nodes: key list -> 'a T -> 'a T
    25   val add_edge: key * key -> 'a T -> 'a T
    26   val add_edge: key * key -> 'a T -> 'a T
    26   val del_edge: key * key -> 'a T -> 'a T
    27   val del_edge: key * key -> 'a T -> 'a T
    27   exception CYCLES of key list list
    28   exception CYCLES of key list list
    28   val add_edge_acyclic: key * key -> 'a T -> 'a T
    29   val add_edge_acyclic: key * key -> 'a T -> 'a T
    29 end;
    30 end;
    45 val op ins_key = gen_ins eq_key;
    46 val op ins_key = gen_ins eq_key;
    46 
    47 
    47 infix del_key;
    48 infix del_key;
    48 fun xs del_key x = if x mem_key xs then gen_rem eq_key (xs, x) else xs;
    49 fun xs del_key x = if x mem_key xs then gen_rem eq_key (xs, x) else xs;
    49 
    50 
       
    51 infix del_keys;
       
    52 val op del_keys = foldl (op del_key);
       
    53 
    50 
    54 
    51 (* tables and sets of keys *)
    55 (* tables and sets of keys *)
    52 
    56 
    53 structure Table = TableFun(Key);
    57 structure Table = TableFun(Key);
    54 type keys = unit Table.table;
    58 type keys = unit Table.table;
    59 fun x mem_keys tab = is_some (Table.lookup (tab: keys, x));
    63 fun x mem_keys tab = is_some (Table.lookup (tab: keys, x));
    60 
    64 
    61 infix ins_keys;
    65 infix ins_keys;
    62 fun x ins_keys tab = if x mem_keys tab then tab else Table.update ((x, ()), tab);
    66 fun x ins_keys tab = if x mem_keys tab then tab else Table.update ((x, ()), tab);
    63 
    67 
    64 fun dest_keys tab = rev (Table.foldl (fn (xs, (x, ())) => x :: xs) ([], tab: keys));
       
    65 
       
    66 
    68 
    67 (* graphs *)
    69 (* graphs *)
    68 
    70 
    69 datatype 'a T = Graph of ('a * (key list * key list)) Table.table;
    71 datatype 'a T = Graph of ('a * (key list * key list)) Table.table;
    70 
    72 
    71 exception UNDEFINED of key;
    73 exception UNDEFINED of key;
    72 
    74 
    73 val empty = Graph Table.empty;
    75 val empty = Graph Table.empty;
       
    76 fun keys (Graph tab) = Table.keys tab;
    74 
    77 
    75 fun get_entry (Graph tab) x =
    78 fun get_entry (Graph tab) x =
    76   (case Table.lookup (tab, x) of
    79   (case Table.lookup (tab, x) of
    77     Some entry => entry
    80     Some entry => entry
    78   | None => raise UNDEFINED x);
    81   | None => raise UNDEFINED x);
    80 fun map_entry x f (G as Graph tab) = Graph (Table.update ((x, f (get_entry G x)), tab));
    83 fun map_entry x f (G as Graph tab) = Graph (Table.update ((x, f (get_entry G x)), tab));
    81 
    84 
    82 
    85 
    83 (* nodes *)
    86 (* nodes *)
    84 
    87 
    85 fun get_nodes (Graph tab) =
       
    86   rev (Table.foldl (fn (nodes, (x, (i, _))) => (x, i) :: nodes) ([], tab));
       
    87 
       
    88 fun map_nodes f (Graph tab) = Graph (Table.map (fn (i, ps) => (f i, ps)) tab);
    88 fun map_nodes f (Graph tab) = Graph (Table.map (fn (i, ps) => (f i, ps)) tab);
    89 
    89 
    90 fun get_node G = #1 o get_entry G;
    90 fun get_node G = #1 o get_entry G;
    91 fun map_node x f = map_entry x (fn (i, ps) => (f i, ps));
    91 fun map_node x f = map_entry x (fn (i, ps) => (f i, ps));
    92 
    92 
    93 
    93 
    94 (* reachability *)
    94 (* reachability *)
    95 
    95 
       
    96 (*nodes reachable from xs -- topologically sorted for acyclic graphs*)
    96 fun reachable next xs =
    97 fun reachable next xs =
    97   let
    98   let
    98     fun reach (R, x) =
    99     fun reach ((rs, R), x) =
    99       if x mem_keys R then R
   100       if x mem_keys R then (rs, R)
   100       else reachs (x ins_keys R, next x)
   101       else apfst (cons x) (reachs ((rs, x ins_keys R), next x))
   101     and reachs R_xs = foldl reach R_xs;
   102     and reachs R_xs = foldl reach R_xs;
   102   in reachs (empty_keys, xs) end;
   103   in reachs (([], empty_keys), xs) end;
   103 
   104 
   104 (*immediate*)
   105 (*immediate*)
   105 fun imm_preds G = #1 o #2 o get_entry G;
   106 fun imm_preds G = #1 o #2 o get_entry G;
   106 fun imm_succs G = #2 o #2 o get_entry G;
   107 fun imm_succs G = #2 o #2 o get_entry G;
   107 
   108 
   108 (*transitive*)
   109 (*transitive*)
   109 fun all_preds G = dest_keys o reachable (imm_preds G);
   110 fun all_preds G = #1 o reachable (imm_preds G);
   110 fun all_succs G = dest_keys o reachable (imm_succs G);
   111 fun all_succs G = #1 o reachable (imm_succs G);
   111 
   112 
   112 
   113 
   113 (* paths *)
   114 (* paths *)
   114 
   115 
   115 fun find_paths G (x, y) =
   116 fun find_paths G (x, y) =
   116   let
   117   let
   117     val X = reachable (imm_succs G) [x];
   118     val (_, X) = reachable (imm_succs G) [x];
   118     fun paths ps p =
   119     fun paths ps p =
   119       if eq_key (p, x) then [p :: ps]
   120       if eq_key (p, x) then [p :: ps]
   120       else flat (map (paths (p :: ps))
   121       else flat (map (paths (p :: ps))
   121         (filter (fn pp => pp mem_keys X andalso not (pp mem_key ps)) (imm_preds G p)));
   122         (filter (fn pp => pp mem_keys X andalso not (pp mem_key ps)) (imm_preds G p)));
   122   in get_entry G y; if y mem_keys X then (paths [] y) else [] end;
   123   in get_entry G y; if y mem_keys X then (paths [] y) else [] end;
   127 exception DUPLICATE of key;
   128 exception DUPLICATE of key;
   128 
   129 
   129 fun new_node (x, info) (Graph tab) =
   130 fun new_node (x, info) (Graph tab) =
   130   Graph (Table.update_new ((x, (info, ([], []))), tab)
   131   Graph (Table.update_new ((x, (info, ([], []))), tab)
   131     handle Table.DUP key => raise DUPLICATE key);
   132     handle Table.DUP key => raise DUPLICATE key);
       
   133 
       
   134 fun del_nodes xs (Graph tab) =
       
   135   let
       
   136     fun del (x, (i, (preds, succs))) =
       
   137       if x mem_key xs then None
       
   138       else Some (x, (i, (preds del_keys xs, succs del_keys xs)));
       
   139   in Graph (Table.make (mapfilter del (Table.dest tab))) end;
   132 
   140 
   133 
   141 
   134 fun add_edge (x, y) =
   142 fun add_edge (x, y) =
   135   map_entry x (fn (i, (preds, succs)) => (i, (preds, y ins_key succs))) o
   143   map_entry x (fn (i, (preds, succs)) => (i, (preds, y ins_key succs))) o
   136    map_entry y (fn (i, (preds, succs)) => (i, (x ins_key preds, succs)));
   144    map_entry y (fn (i, (preds, succs)) => (i, (x ins_key preds, succs)));