Annotation of researchv10no/cmd/sml/src/util/union.sml, revision 1.1.1.1

1.1       root        1: (* Copyright 1989 by AT&T Bell Laboratories *)
                      2: signature UNIONFIND =
                      3:   sig
                      4:     exception Union
                      5:     val new : (int -> bool) ->
                      6:              {union: int * int -> int,
                      7:               find : int -> int}
                      8:   end
                      9: 
                     10: 
                     11: structure Unionfind : UNIONFIND =
                     12:   struct
                     13:     exception Union
                     14:     fun new (fixed) =
                     15:        let open Intmap (* locally rebinding new, of course! *)
                     16:            exception UnionM and UnionN
                     17:            val m = new(32, UnionM) : int intmap
                     18:            and n = new(32, UnionN) : int intmap
                     19:            fun find x = 
                     20:                 let val z = find(map m x)
                     21:                  in add m (x,z); z
                     22:                 end 
                     23:                 handle UnionM => x
                     24:            fun union (x,y) =
                     25:                let val x' = find x and y' = find y
                     26:                    val xn = map n x'  handle UnionN => 1
                     27:                    and yn = map n y'  handle UnionN => 1
                     28:                 in if x' <> y'
                     29:                    then if fixed(x')
                     30:                         then if fixed(y')
                     31:                              then raise Union
                     32:                              else (add m (y', x'); add n (x',xn+yn); x')
                     33:                         else if fixed(y')
                     34:                              then (add m (x', y'); add n (y',xn+yn); y')
                     35:                              else if xn < yn                         
                     36:                              then (add m (x', y'); add n (y',xn+yn); y')
                     37:                              else (add m (y', x'); add n (x',xn+yn); x')
                     38:                    else x'
                     39:                end
                     40:         in {union=union, find=find}
                     41:        end
                     42:   end
                     43: 
                     44: 
                     45: signature SIBLINGS =
                     46:   sig
                     47:     type 't siblingClass
                     48:     val new : (int -> bool) -> '1t siblingClass
                     49:      (* assoc(i,x) must be called for any element i before 
                     50:         i is used as an argument to union or find or getassoc *)
                     51:   end
                     52: 
                     53: 
                     54: structure Siblings : SIBLINGS =
                     55:   struct
                     56:     type 't siblingClass =
                     57:              {assoc : int * 't -> unit,
                     58:               union : int * int -> int,
                     59:                find : int -> int,
                     60:               getassoc : int -> 't list}
                     61:     fun new(fixed: int -> bool) : '1t siblingClass =
                     62:        let val {union = uni, find = find} = Unionfind.new(fixed)
                     63:            exception UnionA
                     64:            val a = Intmap.new(32, UnionA) : ('1t * int list) Intmap.intmap
                     65:            val add = Intmap.add a
                     66:            val map = Intmap.map a
                     67:            fun assoc (i,x) = 
                     68:                let val (_,l) = map i handle UnionA => (x,nil)
                     69:                 in add (i,(x,l))
                     70:                end
                     71:            fun join(i,j) =
                     72:              let val (x,l) = map j
                     73:               in add (j,(x,i::l)); j
                     74:              end
                     75:            fun union (i,j) = 
                     76:                let val i' = find i and j' = find j
                     77:                 in if i' = j' then i'
                     78:                    else let val k = uni(i',j')
                     79:                          in if k=i' then join(j',k) else join(i',k)
                     80:                         end
                     81:                end
                     82:            fun get(i,l) = 
                     83:               let fun f (a::b) = get(a,f(b)) | f nil = l
                     84:                   val (x,r) = map i
                     85:                in x::f(r)
                     86:               end
                     87:            fun getassoc i = get(find i,nil)
                     88:         in {assoc=assoc, union=union, find=find, getassoc=getassoc}
                     89:        end
                     90:   end (* structure Siblings *)
                     91: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.