~ubuntu-branches/ubuntu/lucid/camomile/lucid

« back to all changes in this revision

Viewing changes to toolslib/absOrd.ml

  • Committer: Bazaar Package Importer
  • Author(s): Sylvain Le Gall
  • Date: 2005-12-03 01:18:55 UTC
  • Revision ID: james.westby@ubuntu.com-20051203011855-qzvwlld1xyqnl62t
Tags: upstream-0.6.3
ImportĀ upstreamĀ versionĀ 0.6.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
(* $Id: absOrd.ml,v 1.5 2003/06/18 15:11:06 yori Exp $ *)
 
2
(* Copyright 2002 Yamagata Yoriyuki *)
 
3
 
 
4
type point = int
 
5
 
 
6
module Int = struct type t = int let compare = (-) end
 
7
 
 
8
module Set = ISet
 
9
module Map = Map.Make (Int)
 
10
module IntSet = Set
 
11
module IntMap = Map
 
12
 
 
13
type node = 
 
14
    Empty | Leaf of point
 
15
  | Node of Set.t * node * node * int
 
16
 
 
17
module Node =
 
18
struct
 
19
let height = function
 
20
    Empty -> 0
 
21
  | Leaf _  -> 1
 
22
  | Node (_, _, _, h) -> h
 
23
 
 
24
let elts = function
 
25
    Empty -> Set.empty
 
26
  | Leaf p -> Set.add p Set.empty
 
27
  | Node (s, _, _, _) -> s
 
28
 
 
29
let create l r =
 
30
  match l, r with
 
31
    Empty, _ -> r
 
32
  | _, Empty -> l
 
33
  | _ ->
 
34
      let hl = height l in
 
35
      let hr = height r in
 
36
      let h = 1 + max hl hr in
 
37
      let s = Set.union (elts l) (elts r) in
 
38
      Node (s, l, r, h)
 
39
        
 
40
let rec bal = function
 
41
    Empty -> Empty
 
42
  | Leaf _ as s -> s
 
43
  | Node (s, l, r, _) as node ->
 
44
  let hl = height l in
 
45
  let hr = height r in
 
46
  if hl - hr > 2 then
 
47
    match l with
 
48
      Node (ls, ll, lr, _) ->
 
49
        let hll = height ll in
 
50
        let hlr = height lr in
 
51
        if hll >= hlr then
 
52
          Node (s, ll, concat lr r, 1 + hll)
 
53
        else
 
54
          (match lr with
 
55
            Node (_, lrl, lrr, _) ->
 
56
              let l' = concat ll lrl in
 
57
              let r' = concat lrr r in
 
58
              let h = 1 + max (height l') (height r') in
 
59
              Node (s, l', r', h)
 
60
          | _ -> assert false)
 
61
    |   _ -> assert false
 
62
  else if hr - hl > 2 then
 
63
    match r with
 
64
      Node (rs, rl, rr, _) ->
 
65
        let hrl = height rl in
 
66
        let hrr = height rr in
 
67
        if hrl <= hrr then
 
68
          Node (s, concat l rl, rr, 1 + hrr)
 
69
        else
 
70
          (match rl with
 
71
            Node (_, rll, rlr, _) ->
 
72
              let l' = concat l rll in
 
73
              let r' = concat rlr rr in
 
74
              let h = 1 + max (height l') (height r') in
 
75
              Node (s, l', r', h)
 
76
          | _ -> assert false)
 
77
    |   _ -> assert false
 
78
  else node
 
79
 
 
80
and concat l r = bal (create l r)
 
81
 
 
82
let mem p  = function
 
83
    Empty -> false
 
84
  | Leaf p' -> (p = p')
 
85
  | Node (s, _, _, _) -> Set.mem p s
 
86
 
 
87
let rec compare p1 p2 = function
 
88
    Empty -> raise Not_found
 
89
  | Leaf p ->
 
90
      if p1 = p && p2 = p then 0 else 
 
91
      raise Not_found
 
92
  | Node (s, s1, s2, _) ->
 
93
      if mem p1 s1 then
 
94
        if mem p2 s1 then compare p1 p2 s1 else
 
95
        if mem p2 s2 then -1 else
 
96
        raise Not_found
 
97
      else if mem p1 s2 then
 
98
        if mem p2 s1 then 1 else
 
99
        if mem p2 s2 then compare p1 p2 s2 else
 
100
        raise Not_found
 
101
      else
 
102
        raise Not_found
 
103
 
 
104
let rec top = function
 
105
    Empty -> raise Not_found
 
106
  |     Leaf p -> p
 
107
  |     Node (_, s1, s2, _) -> 
 
108
      try top s2 with Not_found -> top s1
 
109
 
 
110
let rec top_in m = function
 
111
    Empty -> raise Not_found
 
112
  | Leaf p ->
 
113
      if Map.mem p m then p else raise Not_found
 
114
  | Node (_, s1, s2, _) ->
 
115
      try top_in m s2 with Not_found -> top_in m s1
 
116
 
 
117
let rec bottom = function
 
118
    Empty -> raise Not_found
 
119
  |     Leaf p -> p
 
120
  |     Node (_, s1, s2, _) -> 
 
121
      try bottom s1 with Not_found -> bottom s2
 
122
 
 
123
let rec bottom_in m = function
 
124
    Empty -> raise Not_found
 
125
  | Leaf p ->
 
126
      if Map.mem p m then p else raise Not_found
 
127
  | Node (_, s1, s2, _) ->
 
128
      try bottom_in m s1 with Not_found -> bottom_in m s1
 
129
 
 
130
let rec next p = function
 
131
    Empty -> raise Not_found
 
132
  |     Leaf _ -> raise Not_found
 
133
  |     Node (_, s1, s2, _) ->
 
134
      if mem p s1 then try next p s1 with Not_found -> bottom s2 else
 
135
      next p s2
 
136
 
 
137
let rec prev p = function
 
138
    Empty -> raise Not_found
 
139
  |     Leaf _ -> raise Not_found
 
140
  |     Node (_, s1, s2, _) ->
 
141
      if mem p s2 then try prev p s2 with Not_found -> top s1 else
 
142
      prev p s1
 
143
 
 
144
let rec before p = function
 
145
    Empty -> Empty
 
146
  | Leaf p' ->
 
147
      if p = p' then Empty else raise Not_found
 
148
  | Node (_, s1, s2, h) ->
 
149
      if mem p s1 then
 
150
        before p s1
 
151
      else
 
152
        concat s1 (before p s2)
 
153
 
 
154
let rec upto p = function
 
155
    Empty -> Empty
 
156
  | Leaf p' as s -> 
 
157
      if p = p' then s else raise Not_found
 
158
  | Node (_, s1, s2, h) ->
 
159
      if mem p s1 then
 
160
        upto p s1
 
161
      else
 
162
        concat s1 (upto p s2)
 
163
 
 
164
let rec after p = function
 
165
    Empty -> Empty
 
166
  | Leaf p' ->
 
167
      if p = p' then Empty else raise Not_found
 
168
  | Node (_, s1, s2, h) ->
 
169
      if mem p s1 then
 
170
        concat (after p s1) s2
 
171
      else
 
172
        after p s2
 
173
 
 
174
let rec from p = function
 
175
    Empty -> Empty
 
176
  | Leaf p' as s ->
 
177
      if p = p' then s else raise Not_found
 
178
  | Node (_, s1, s2, h) ->
 
179
      if mem p s1 then
 
180
        concat (from p s1) s2
 
181
      else
 
182
        from p s2
 
183
 
 
184
let rec iter proc = function
 
185
    Empty -> ()
 
186
  | Leaf p -> proc p
 
187
  | Node (_, s1, s2, _) -> 
 
188
      iter proc s1; 
 
189
      iter proc s2
 
190
 
 
191
let rec fold f s init =
 
192
  match s with
 
193
    Empty -> init
 
194
  | Leaf p -> f p init
 
195
  | Node (_, s1, s2, _) ->
 
196
      fold f s2 (fold f s1 init)
 
197
 
 
198
let rec put_to_top p = function
 
199
    Empty -> Leaf p
 
200
  | Leaf _ as s1 -> create s1 (Leaf p)
 
201
  | Node (s, s1, s2, h) ->
 
202
      let s' = Set.add p s in
 
203
      let s2' = put_to_top p s2 in
 
204
      let h = 1 + max (height s1) (height s2') in
 
205
      bal (Node (s', s1, s2', h))
 
206
 
 
207
let rec put_to_bottom p = function
 
208
    Empty -> Leaf p
 
209
  | Leaf _ as s2 -> create (Leaf p) s2
 
210
  | Node (s, s1, s2, h) ->
 
211
      let s' = Set.add p s in
 
212
      let s1' = put_to_bottom p s1 in
 
213
      let h = 1 + max (height s1') (height s2) in
 
214
      bal (Node (s', s1', s2, h))
 
215
 
 
216
let rec put_before p0 p = function
 
217
    Empty -> raise Not_found
 
218
  | Leaf p1 as s ->
 
219
      if p1 = p0 then create (Leaf p) s else raise Not_found
 
220
  | Node (s, s1, s2, h) ->
 
221
      let s' = Set.add p s in
 
222
      let s1', s2' =
 
223
        if mem p0 s1 then (put_before p0 p s1), s2 else
 
224
        s1, (put_before p0 p s2)
 
225
      in
 
226
      let h = 1 + max (height s1') (height s2') in
 
227
      bal (Node (s', s1', s2', h))
 
228
 
 
229
let rec put_after p0 p = function
 
230
    Empty -> raise Not_found
 
231
  | Leaf p1 as s ->
 
232
      if p1 = p0 then create s (Leaf p) else raise Not_found
 
233
  | Node (s, s1, s2, h) ->
 
234
      let s' = Set.add p s in
 
235
      let s1', s2' =
 
236
        if mem p0 s1 then (put_after p0 p s1), s2 else
 
237
        s1, (put_after p0 p s2)
 
238
      in
 
239
      let h = 1 + max (height s1') (height s2') in
 
240
      bal (Node (s', s1', s2', h))
 
241
 
 
242
end
 
243
 
 
244
type t = node * int
 
245
 
 
246
let compare p1 p2 (node, _) = Node.compare p1 p2 node
 
247
let top (node, _) = Node.top node
 
248
let bottom (node, _) = Node.bottom node
 
249
let next p (node, _) = Node.next p node
 
250
let prev p (node, _) = Node.prev p node
 
251
 
 
252
let add_top (node, id) = (id, (Node.put_to_top id node, id + 1))
 
253
 
 
254
let add_bottom (node, id) = (id, (Node.put_to_bottom id node, id + 1))
 
255
 
 
256
let add_before p (node, id) =
 
257
  let l = Node.before p node in
 
258
  let r = Node.from p node in
 
259
  (id, (Node.put_before p id node, id + 1))
 
260
 
 
261
let add_after p (node, id) =
 
262
  let l = Node.upto p node in
 
263
  let r = Node.after p node in
 
264
  (id, (Node.put_after p id node, id + 1))
 
265
 
 
266
let iter proc (node, _) = Node.iter proc node
 
267
let fold f (node, _) init = Node.fold f node init
 
268
 
 
269
let rec import_aux a i j w2p p2w id =
 
270
  if i = j then
 
271
    (Leaf id, IntMap.add a.(i) id w2p, Map.add id a.(i) p2w, id + 1)
 
272
  else
 
273
    let i' = i + (j - i) / 2 in
 
274
    let ord1, w2p, p2w, id = import_aux a i i' w2p p2w id in
 
275
    let ord2, w2p, p2w, id = import_aux a (i' + 1) j w2p p2w id in
 
276
    (Node.concat ord1 ord2, w2p, p2w, id)
 
277
 
 
278
let import weights =
 
279
  let set = List.fold_left (fun set w ->
 
280
    IntSet.add w set) 
 
281
      IntSet.empty 
 
282
      weights 
 
283
  in
 
284
  let weights = IntSet.fold (fun w ws -> w :: ws) set [] in
 
285
  let a = Array.of_list weights in
 
286
  Array.sort (-) a;
 
287
  let node, w2p, p2w, id = 
 
288
    import_aux a 0 (Array.length a - 1) IntMap.empty Map.empty 0
 
289
  in
 
290
  ((node, id), w2p, p2w)