wttree.scm 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. ;; -*-Scheme-*-
  2. ;;
  3. ;; $Id: wttree.scm,v 1.1 1994/11/28 21:58:48 adams Exp adams $
  4. ;;
  5. ;; Copyright (c) 1993-1994 Stephen Adams
  6. ;;
  7. ;; References:
  8. ;;
  9. ;; Stephen Adams, Implemeting Sets Efficiently in a Functional
  10. ;; Language, CSTR 92-10, Department of Electronics and Computer
  11. ;; Science, University of Southampton, 1992
  12. ;;
  13. ;;
  14. ;; Copyright (c) 1993-94 Massachusetts Institute of Technology
  15. ;;
  16. ;; This material was developed by the Scheme project at the Massachusetts
  17. ;; Institute of Technology, Department of Electrical Engineering and
  18. ;; Computer Science. Permission to copy this software, to redistribute
  19. ;; it, and to use it for any purpose is granted, subject to the following
  20. ;; restrictions and understandings.
  21. ;;
  22. ;; 1. Any copy made of this software must include this copyright notice
  23. ;; in full.
  24. ;;
  25. ;; 2. Users of this software agree to make their best efforts (a) to
  26. ;; return to the MIT Scheme project any improvements or extensions that
  27. ;; they make, so that these may be included in future releases; and (b)
  28. ;; to inform MIT of noteworthy uses of this software.
  29. ;;
  30. ;; 3. All materials developed as a consequence of the use of this
  31. ;; software shall duly acknowledge such use, in accordance with the usual
  32. ;; standards of acknowledging credit in academic research.
  33. ;;
  34. ;; 4. MIT has made no warrantee or representation that the operation of
  35. ;; this software will be error-free, and MIT is under no obligation to
  36. ;; provide any services, by way of maintenance, update, or otherwise.
  37. ;;
  38. ;; 5. In conjunction with products arising from the use of this material,
  39. ;; there shall be no use of the name of the Massachusetts Institute of
  40. ;; Technology nor of any adaptation thereof in any advertising,
  41. ;; promotional, or sales literature without prior written consent from
  42. ;; MIT in each case.
  43. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  44. ;;
  45. ;; Weight Balanced Binary Trees
  46. ;;
  47. ;;
  48. ;;
  49. ;; This file has been modified from the MIT-Scheme library version to
  50. ;; make it more standard. The main changes are
  51. ;;
  52. ;; . The whole thing has been put in a LET as R4RS Scheme has no module
  53. ;; system.
  54. ;; . The MIT-Scheme define structure operations have been written out by
  55. ;; hand.
  56. ;;
  57. ;; It has been tested on MIT-Scheme, scheme48 and scm4e1
  58. ;;
  59. ;; Non-standard procedures:
  60. ;; error
  61. ;; error:wrong-type-argument
  62. ;; error:band-range-argument
  63. ;; These are only called when there is an error so it is not critical to
  64. ;; have them defined :-)
  65. ;;
  66. ;;
  67. ;; If your system has a compiler and you want this code to run fast, you
  68. ;; should do whatever is necessary to inline all of the structure accessors.
  69. ;;
  70. ;; This is MIT-Scheme's way of saying that +, car etc should all be inlined.
  71. ;;
  72. ;;(declare (usual-integrations))
  73. ;;;
  74. ;;; Interface to this package.
  75. ;;;
  76. ;;; ONLY these procedures (and TEST at the end of the file) will be
  77. ;;; (re)defined in your system.
  78. ;;;
  79. (define make-wt-tree-type #f)
  80. (define number-wt-type #f)
  81. (define string-wt-type #f)
  82. (define make-wt-tree #f)
  83. (define singleton-wt-tree #f)
  84. (define alist->wt-tree #f)
  85. (define wt-tree/empty? #f)
  86. (define wt-tree/size #f)
  87. (define wt-tree/add #f)
  88. (define wt-tree/delete #f)
  89. (define wt-tree/add! #f)
  90. (define wt-tree/delete! #f)
  91. (define wt-tree/member? #f)
  92. (define wt-tree/lookup #f)
  93. (define wt-tree/split< #f)
  94. (define wt-tree/split> #f)
  95. (define wt-tree/union #f)
  96. (define wt-tree/intersection #f)
  97. (define wt-tree/difference #f)
  98. (define wt-tree/subset? #f)
  99. (define wt-tree/set-equal? #f)
  100. (define wt-tree/fold #f)
  101. (define wt-tree/for-each #f)
  102. (define wt-tree/index #f)
  103. (define wt-tree/index-datum #f)
  104. (define wt-tree/index-pair #f)
  105. (define wt-tree/rank #f)
  106. (define wt-tree/min #f)
  107. (define wt-tree/min-datum #f)
  108. (define wt-tree/min-pair #f)
  109. (define wt-tree/delete-min #f)
  110. (define wt-tree/delete-min! #f)
  111. ;; This LET sets all of the above variables.
  112. (let ()
  113. ;; We use the folowing MIT-Scheme operation on fixnums (small
  114. ;; integers). R4RS compatible (but less efficient) definitions.
  115. ;; You should replace these with something that is efficient in your
  116. ;; system.
  117. (define fix:fixnum? (lambda (x) (and (exact? x) (integer? x))))
  118. (define fix:+ +)
  119. (define fix:- -)
  120. (define fix:< <)
  121. (define fix:<= <)
  122. (define fix:> >)
  123. (define fix:* *)
  124. ;; A TREE-TYPE is a collection of those procedures that depend on the
  125. ;; ordering relation.
  126. ;; MIT-Scheme structure definition
  127. ;;(define-structure
  128. ;; (tree-type
  129. ;; (conc-name tree-type/)
  130. ;; (constructor %make-tree-type))
  131. ;; (key<? #F read-only true)
  132. ;; (alist->tree #F read-only true)
  133. ;; (add #F read-only true)
  134. ;; (insert! #F read-only true)
  135. ;; (delete #F read-only true)
  136. ;; (delete! #F read-only true)
  137. ;; (member? #F read-only true)
  138. ;; (lookup #F read-only true)
  139. ;; (split-lt #F read-only true)
  140. ;; (split-gt #F read-only true)
  141. ;; (union #F read-only true)
  142. ;; (intersection #F read-only true)
  143. ;; (difference #F read-only true)
  144. ;; (subset? #F read-only true)
  145. ;; (rank #F read-only true)
  146. ;;)
  147. ;; Written out by hand, using vectors:
  148. ;;
  149. ;; If possible, you should teach your system to print out something
  150. ;; like #[tree-type <] instread of the whole vector.
  151. (define tag:tree-type (string->symbol "#[(runtime wttree)tree-type]"))
  152. (define (%make-tree-type key<? alist->tree
  153. add insert!
  154. delete delete!
  155. member? lookup
  156. split-lt split-gt
  157. union intersection
  158. difference subset?
  159. rank)
  160. (vector tag:tree-type
  161. key<? alist->tree add insert!
  162. delete delete! member? lookup
  163. split-lt split-gt union intersection
  164. difference subset? rank))
  165. (define (tree-type? tt)
  166. (and (vector? tt)
  167. (eq? (vector-ref tt 0) tag:tree-type)))
  168. (define (tree-type/key<? tt) (vector-ref tt 1))
  169. (define (tree-type/alist->tree tt) (vector-ref tt 2))
  170. (define (tree-type/add tt) (vector-ref tt 3))
  171. (define (tree-type/insert! tt) (vector-ref tt 4))
  172. (define (tree-type/delete tt) (vector-ref tt 5))
  173. (define (tree-type/delete! tt) (vector-ref tt 6))
  174. (define (tree-type/member? tt) (vector-ref tt 7))
  175. (define (tree-type/lookup tt) (vector-ref tt 8))
  176. (define (tree-type/split-lt tt) (vector-ref tt 9))
  177. (define (tree-type/split-gt tt) (vector-ref tt 10))
  178. (define (tree-type/union tt) (vector-ref tt 11))
  179. (define (tree-type/intersection tt) (vector-ref tt 12))
  180. (define (tree-type/difference tt) (vector-ref tt 13))
  181. (define (tree-type/subset? tt) (vector-ref tt 14))
  182. (define (tree-type/rank tt) (vector-ref tt 15))
  183. ;; User level tree representation.
  184. ;;
  185. ;; WT-TREE is a wrapper for trees of nodes.
  186. ;;
  187. ;;MIT-Scheme:
  188. ;;(define-structure
  189. ;; (wt-tree
  190. ;; (conc-name tree/)
  191. ;; (constructor %make-wt-tree))
  192. ;; (type #F read-only true)
  193. ;; (root #F read-only false))
  194. ;; If possible, you should teach your system to print out something
  195. ;; like #[wt-tree] instread of the whole vector.
  196. (define tag:wt-tree (string->symbol "#[(runtime wttree)wt-tree]"))
  197. (define (%make-wt-tree type root)
  198. (vector tag:wt-tree type root))
  199. (define (wt-tree? t)
  200. (and (vector? t)
  201. (eq? (vector-ref t 0) tag:wt-tree)))
  202. (define (tree/type t) (vector-ref t 1))
  203. (define (tree/root t) (vector-ref t 2))
  204. (define (set-tree/root! t v) (vector-set! t 2 v))
  205. ;; Nodes are the thing from which the real trees are built. There are
  206. ;; lots of these and the uninquisitibe user will never see them, so
  207. ;; they are represented as untagged to save the slot that would be
  208. ;; used for tagging structures.
  209. ;; In MIT-Scheme these were all DEFINE-INTEGRABLE
  210. (define (make-node k v l r w) (vector w l k r v))
  211. (define (node/k node) (vector-ref node 2))
  212. (define (node/v node) (vector-ref node 4))
  213. (define (node/l node) (vector-ref node 1))
  214. (define (node/r node) (vector-ref node 3))
  215. (define (node/w node) (vector-ref node 0))
  216. (define empty 'empty)
  217. (define (empty? x) (eq? x 'empty))
  218. (define (node/size node)
  219. (if (empty? node) 0 (node/w node)))
  220. (define (node/singleton k v) (make-node k v empty empty 1))
  221. (define (with-n-node node receiver)
  222. (receiver (node/k node) (node/v node) (node/l node) (node/r node)))
  223. ;;
  224. ;; Constructors for building node trees of various complexity
  225. ;;
  226. (define (n-join k v l r)
  227. (make-node k v l r (fix:+ 1 (fix:+ (node/size l) (node/size r)))))
  228. (define (single-l a.k a.v x r)
  229. (with-n-node r
  230. (lambda (b.k b.v y z) (n-join b.k b.v (n-join a.k a.v x y) z))))
  231. (define (double-l a.k a.v x r)
  232. (with-n-node r
  233. (lambda (c.k c.v r.l z)
  234. (with-n-node r.l
  235. (lambda (b.k b.v y1 y2)
  236. (n-join b.k b.v
  237. (n-join a.k a.v x y1)
  238. (n-join c.k c.v y2 z)))))))
  239. (define (single-r b.k b.v l z)
  240. (with-n-node l
  241. (lambda (a.k a.v x y) (n-join a.k a.v x (n-join b.k b.v y z)))))
  242. (define (double-r c.k c.v l z)
  243. (with-n-node l
  244. (lambda (a.k a.v x l.r)
  245. (with-n-node l.r
  246. (lambda (b.k b.v y1 y2)
  247. (n-join b.k b.v
  248. (n-join a.k a.v x y1)
  249. (n-join c.k c.v y2 z)))))))
  250. ;; (define-integrable wt-tree-ratio 5)
  251. (define wt-tree-ratio 5)
  252. (define (t-join k v l r)
  253. (define (simple-join) (n-join k v l r))
  254. (let ((l.n (node/size l))
  255. (r.n (node/size r)))
  256. (cond ((fix:< (fix:+ l.n r.n) 2) (simple-join))
  257. ((fix:> r.n (fix:* wt-tree-ratio l.n))
  258. ;; right is too big
  259. (let ((r.l.n (node/size (node/l r)))
  260. (r.r.n (node/size (node/r r))))
  261. (if (fix:< r.l.n r.r.n)
  262. (single-l k v l r)
  263. (double-l k v l r))))
  264. ((fix:> l.n (fix:* wt-tree-ratio r.n))
  265. ;; left is too big
  266. (let ((l.l.n (node/size (node/l l)))
  267. (l.r.n (node/size (node/r l))))
  268. (if (fix:< l.r.n l.l.n)
  269. (single-r k v l r)
  270. (double-r k v l r))))
  271. (else
  272. (simple-join)))))
  273. ;;
  274. ;; Node tree procedures that are independent of key<?
  275. ;;
  276. (define (node/min node)
  277. (cond ((empty? node) (error:empty 'min))
  278. ((empty? (node/l node)) node)
  279. (else (node/min (node/l node)))))
  280. (define (node/delmin node)
  281. (cond ((empty? node) (error:empty 'delmin))
  282. ((empty? (node/l node)) (node/r node))
  283. (else (t-join (node/k node) (node/v node)
  284. (node/delmin (node/l node)) (node/r node)))))
  285. (define (node/concat2 node1 node2)
  286. (cond ((empty? node1) node2)
  287. ((empty? node2) node1)
  288. (else
  289. (let ((min-node (node/min node2)))
  290. (t-join (node/k min-node) (node/v min-node)
  291. node1 (node/delmin node2))))))
  292. (define (node/inorder-fold procedure base node)
  293. (define (fold base node)
  294. (if (empty? node)
  295. base
  296. (with-n-node node
  297. (lambda (k v l r)
  298. (fold (procedure k v (fold base r)) l)))))
  299. (fold base node))
  300. (define (node/for-each procedure node)
  301. (if (not (empty? node))
  302. (with-n-node node
  303. (lambda (k v l r)
  304. (node/for-each procedure l)
  305. (procedure k v)
  306. (node/for-each procedure r)))))
  307. (define (node/height node)
  308. (if (empty? node)
  309. 0
  310. (+ 1 (max (node/height (node/l node))
  311. (node/height (node/r node))))))
  312. (define (node/index node index)
  313. (define (loop node index)
  314. (let ((size.l (node/size (node/l node))))
  315. (cond ((fix:< index size.l) (loop (node/l node) index))
  316. ((fix:> index size.l) (loop (node/r node)
  317. (fix:- index (fix:+ 1 size.l))))
  318. (else node))))
  319. (let ((bound (node/size node)))
  320. (if (or (< index 0)
  321. (>= index bound)
  322. (not (fix:fixnum? index)))
  323. (error:bad-range-argument index 'node/index)
  324. (loop node index))))
  325. (define (error:empty owner)
  326. (error "Operation requires non-empty tree:" owner))
  327. (define (local:make-wt-tree-type key<?)
  328. ;; MIT-Scheme definitions:
  329. ;;(declare (integrate key<?))
  330. ;;(define-integrable (key>? x y) (key<? y x))
  331. (define (key>? x y) (key<? y x))
  332. (define (node/find k node)
  333. ;; Returns either the node or #f.
  334. ;; Loop takes D comparisons where D is the depth of the tree
  335. ;; rather than the traditional compare-low, compare-high which
  336. ;; takes on average 1.5(D-1) comparisons
  337. (define (loop this best)
  338. (cond ((empty? this) best)
  339. ((key<? k (node/k this)) (loop (node/l this) best))
  340. (else (loop (node/r this) this))))
  341. (let ((best (loop node #f)))
  342. (cond ((not best) #f)
  343. ((key<? (node/k best) k) #f)
  344. (else best))))
  345. (define (node/rank k node rank)
  346. (cond ((empty? node) #f)
  347. ((key<? k (node/k node)) (node/rank k (node/l node) rank))
  348. ((key>? k (node/k node))
  349. (node/rank k (node/r node)
  350. (fix:+ 1 (fix:+ rank (node/size (node/l node))))))
  351. (else (fix:+ rank (node/size (node/l node))))))
  352. (define (node/add node k v)
  353. (if (empty? node)
  354. (node/singleton k v)
  355. (with-n-node node
  356. (lambda (key val l r)
  357. (cond ((key<? k key) (t-join key val (node/add l k v) r))
  358. ((key<? key k) (t-join key val l (node/add r k v)))
  359. (else (n-join key v l r)))))))
  360. (define (node/delete x node)
  361. (if (empty? node)
  362. empty
  363. (with-n-node node
  364. (lambda (key val l r)
  365. (cond ((key<? x key) (t-join key val (node/delete x l) r))
  366. ((key<? key x) (t-join key val l (node/delete x r)))
  367. (else (node/concat2 l r)))))))
  368. (define (node/concat tree1 tree2)
  369. (cond ((empty? tree1) tree2)
  370. ((empty? tree2) tree1)
  371. (else
  372. (let ((min-node (node/min tree2)))
  373. (node/concat3 (node/k min-node) (node/v min-node) tree1
  374. (node/delmin tree2))))))
  375. (define (node/concat3 k v l r)
  376. (cond ((empty? l) (node/add r k v))
  377. ((empty? r) (node/add l k v))
  378. (else
  379. (let ((n1 (node/size l))
  380. (n2 (node/size r)))
  381. (cond ((fix:< (fix:* wt-tree-ratio n1) n2)
  382. (with-n-node r
  383. (lambda (k2 v2 l2 r2)
  384. (t-join k2 v2 (node/concat3 k v l l2) r2))))
  385. ((fix:< (fix:* wt-tree-ratio n2) n1)
  386. (with-n-node l
  387. (lambda (k1 v1 l1 r1)
  388. (t-join k1 v1 l1 (node/concat3 k v r1 r)))))
  389. (else
  390. (n-join k v l r)))))))
  391. (define (node/split-lt node x)
  392. (cond ((empty? node) empty)
  393. ((key<? x (node/k node))
  394. (node/split-lt (node/l node) x))
  395. ((key<? (node/k node) x)
  396. (node/concat3 (node/k node) (node/v node) (node/l node)
  397. (node/split-lt (node/r node) x)))
  398. (else (node/l node))))
  399. (define (node/split-gt node x)
  400. (cond ((empty? node) empty)
  401. ((key<? (node/k node) x)
  402. (node/split-gt (node/r node) x))
  403. ((key<? x (node/k node))
  404. (node/concat3 (node/k node) (node/v node)
  405. (node/split-gt (node/l node) x) (node/r node)))
  406. (else (node/r node))))
  407. (define (node/union tree1 tree2)
  408. (cond ((empty? tree1) tree2)
  409. ((empty? tree2) tree1)
  410. (else
  411. (with-n-node tree2
  412. (lambda (ak av l r)
  413. (let ((l1 (node/split-lt tree1 ak))
  414. (r1 (node/split-gt tree1 ak)))
  415. (node/concat3 ak av (node/union l1 l) (node/union r1 r))))))))
  416. (define (node/difference tree1 tree2)
  417. (cond ((empty? tree1) empty)
  418. ((empty? tree2) tree1)
  419. (else
  420. (with-n-node tree2
  421. (lambda (ak av l r)
  422. (let ((l1 (node/split-lt tree1 ak))
  423. (r1 (node/split-gt tree1 ak)))
  424. av
  425. (node/concat (node/difference l1 l)
  426. (node/difference r1 r))))))))
  427. (define (node/intersection tree1 tree2)
  428. (cond ((empty? tree1) empty)
  429. ((empty? tree2) empty)
  430. (else
  431. (with-n-node tree2
  432. (lambda (ak av l r)
  433. (let ((l1 (node/split-lt tree1 ak))
  434. (r1 (node/split-gt tree1 ak)))
  435. (if (node/find ak tree1)
  436. (node/concat3 ak av (node/intersection l1 l)
  437. (node/intersection r1 r))
  438. (node/concat (node/intersection l1 l)
  439. (node/intersection r1 r)))))))))
  440. (define (node/subset? tree1 tree2)
  441. (or (empty? tree1)
  442. (and (fix:<= (node/size tree1) (node/size tree2))
  443. (with-n-node tree1
  444. (lambda (k v l r)
  445. v
  446. (cond ((key<? k (node/k tree2))
  447. (and (node/subset? l (node/l tree2))
  448. (node/find k tree2)
  449. (node/subset? r tree2)))
  450. ((key>? k (node/k tree2))
  451. (and (node/subset? r (node/r tree2))
  452. (node/find k tree2)
  453. (node/subset? l tree2)))
  454. (else
  455. (and (node/subset? l (node/l tree2))
  456. (node/subset? r (node/r tree2))))))))))
  457. ;;; Tree interface: stripping off or injecting the tree types
  458. (define (tree/map-add tree k v)
  459. (%make-wt-tree (tree/type tree)
  460. (node/add (tree/root tree) k v)))
  461. (define (tree/insert! tree k v)
  462. (set-tree/root! tree (node/add (tree/root tree) k v)))
  463. (define (tree/delete tree k)
  464. (%make-wt-tree (tree/type tree)
  465. (node/delete k (tree/root tree))))
  466. (define (tree/delete! tree k)
  467. (set-tree/root! tree (node/delete k (tree/root tree))))
  468. (define (tree/split-lt tree key)
  469. (%make-wt-tree (tree/type tree)
  470. (node/split-lt (tree/root tree) key)))
  471. (define (tree/split-gt tree key)
  472. (%make-wt-tree (tree/type tree)
  473. (node/split-gt (tree/root tree) key)))
  474. (define (tree/union tree1 tree2)
  475. (%make-wt-tree (tree/type tree1)
  476. (node/union (tree/root tree1) (tree/root tree2))))
  477. (define (tree/intersection tree1 tree2)
  478. (%make-wt-tree (tree/type tree1)
  479. (node/intersection (tree/root tree1) (tree/root tree2))))
  480. (define (tree/difference tree1 tree2)
  481. (%make-wt-tree (tree/type tree1)
  482. (node/difference (tree/root tree1) (tree/root tree2))))
  483. (define (tree/subset? tree1 tree2)
  484. (node/subset? (tree/root tree1) (tree/root tree2)))
  485. (define (alist->tree alist)
  486. (define (loop alist node)
  487. (cond ((null? alist) node)
  488. ((pair? alist) (loop (cdr alist)
  489. (node/add node (caar alist) (cdar alist))))
  490. (else
  491. (error:wrong-type-argument alist "alist" 'alist->tree))))
  492. (%make-wt-tree my-type (loop alist empty)))
  493. (define (tree/get tree key default)
  494. (let ((node (node/find key (tree/root tree))))
  495. (if node
  496. (node/v node)
  497. default)))
  498. (define (tree/rank tree key) (node/rank key (tree/root tree) 0))
  499. (define (tree/member? key tree)
  500. (and (node/find key (tree/root tree))
  501. #t))
  502. (define my-type #F)
  503. (set! my-type
  504. (%make-tree-type
  505. key<?; key<?
  506. alist->tree; alist->tree
  507. tree/map-add; add
  508. tree/insert!; insert!
  509. tree/delete; delete
  510. tree/delete!; delete!
  511. tree/member?; member?
  512. tree/get; lookup
  513. tree/split-lt; split-lt
  514. tree/split-gt; split-gt
  515. tree/union; union
  516. tree/intersection; intersection
  517. tree/difference; difference
  518. tree/subset?; subset?
  519. tree/rank; rank
  520. ))
  521. my-type)
  522. (define (guarantee-tree tree procedure)
  523. (if (not (wt-tree? tree))
  524. (error:wrong-type-argument tree "weight-balanced tree" procedure)))
  525. (define (guarantee-tree-type type procedure)
  526. (if (not (tree-type? type))
  527. (error:wrong-type-argument type "weight-balanced tree type" procedure)))
  528. (define (guarantee-compatible-trees tree1 tree2 procedure)
  529. (guarantee-tree tree1 procedure)
  530. (guarantee-tree tree2 procedure)
  531. (if (not (eq? (tree/type tree1) (tree/type tree2)))
  532. (error "The trees" tree1 'and tree2 'have 'incompatible 'types
  533. (tree/type tree1) 'and (tree/type tree2))))
  534. ;;;______________________________________________________________________
  535. ;;;
  536. ;;; Export interface
  537. ;;;
  538. (set! make-wt-tree-type local:make-wt-tree-type)
  539. (set! make-wt-tree
  540. (lambda (tree-type)
  541. (%make-wt-tree tree-type empty)))
  542. (set! singleton-wt-tree
  543. (lambda (type key value)
  544. (guarantee-tree-type type 'singleton-wt-tree)
  545. (%make-wt-tree type (node/singleton key value))))
  546. (set! alist->wt-tree
  547. (lambda (type alist)
  548. (guarantee-tree-type type 'alist->wt-tree)
  549. ((tree-type/alist->tree type) alist)))
  550. (set! wt-tree/empty?
  551. (lambda (tree)
  552. (guarantee-tree tree 'wt-tree/empty?)
  553. (empty? (tree/root tree))))
  554. (set! wt-tree/size
  555. (lambda (tree)
  556. (guarantee-tree tree 'wt-tree/size)
  557. (node/size (tree/root tree))))
  558. (set! wt-tree/add
  559. (lambda (tree key datum)
  560. (guarantee-tree tree 'wt-tree/add)
  561. ((tree-type/add (tree/type tree)) tree key datum)))
  562. (set! wt-tree/delete
  563. (lambda (tree key)
  564. (guarantee-tree tree 'wt-tree/delete)
  565. ((tree-type/delete (tree/type tree)) tree key)))
  566. (set! wt-tree/add!
  567. (lambda (tree key datum)
  568. (guarantee-tree tree 'wt-tree/add!)
  569. ((tree-type/insert! (tree/type tree)) tree key datum)))
  570. (set! wt-tree/delete!
  571. (lambda (tree key)
  572. (guarantee-tree tree 'wt-tree/delete!)
  573. ((tree-type/delete! (tree/type tree)) tree key)))
  574. (set! wt-tree/member?
  575. (lambda (key tree)
  576. (guarantee-tree tree 'wt-tree/member?)
  577. ((tree-type/member? (tree/type tree)) key tree)))
  578. (set! wt-tree/lookup
  579. (lambda (tree key default)
  580. (guarantee-tree tree 'wt-tree/lookup)
  581. ((tree-type/lookup (tree/type tree)) tree key default)))
  582. (set! wt-tree/split<
  583. (lambda (tree key)
  584. (guarantee-tree tree 'wt-tree/split<)
  585. ((tree-type/split-lt (tree/type tree)) tree key)))
  586. (set! wt-tree/split>
  587. (lambda (tree key)
  588. (guarantee-tree tree 'wt-tree/split>)
  589. ((tree-type/split-gt (tree/type tree)) tree key)))
  590. (set! wt-tree/union
  591. (lambda (tree1 tree2)
  592. (guarantee-compatible-trees tree1 tree2 'wt-tree/union)
  593. ((tree-type/union (tree/type tree1)) tree1 tree2)))
  594. (set! wt-tree/intersection
  595. (lambda (tree1 tree2)
  596. (guarantee-compatible-trees tree1 tree2 'wt-tree/intersection)
  597. ((tree-type/intersection (tree/type tree1)) tree1 tree2)))
  598. (set! wt-tree/difference
  599. (lambda (tree1 tree2)
  600. (guarantee-compatible-trees tree1 tree2 'wt-tree/difference)
  601. ((tree-type/difference (tree/type tree1)) tree1 tree2)))
  602. (set! wt-tree/subset?
  603. (lambda (tree1 tree2)
  604. (guarantee-compatible-trees tree1 tree2 'wt-tree/subset?)
  605. ((tree-type/subset? (tree/type tree1)) tree1 tree2)))
  606. (set! wt-tree/set-equal?
  607. (lambda (tree1 tree2)
  608. (and (wt-tree/subset? tree1 tree2)
  609. (wt-tree/subset? tree2 tree1))))
  610. (set! wt-tree/fold
  611. (lambda (combiner-key-datum-result init tree)
  612. (guarantee-tree tree 'wt-tree/fold)
  613. (node/inorder-fold combiner-key-datum-result
  614. init
  615. (tree/root tree))))
  616. (set! wt-tree/for-each
  617. (lambda (action-key-datum tree)
  618. (guarantee-tree tree 'wt-tree/for-each)
  619. (node/for-each action-key-datum (tree/root tree))))
  620. (set! wt-tree/index
  621. (lambda (tree index)
  622. (guarantee-tree tree 'wt-tree/index)
  623. (let ((node (node/index (tree/root tree) index)))
  624. (and node (node/k node)))))
  625. (set! wt-tree/index-datum
  626. (lambda (tree index)
  627. (guarantee-tree tree 'wt-tree/index-datum)
  628. (let ((node (node/index (tree/root tree) index)))
  629. (and node (node/v node)))))
  630. (set! wt-tree/index-pair
  631. (lambda (tree index)
  632. (guarantee-tree tree 'wt-tree/index-pair)
  633. (let ((node (node/index (tree/root tree) index)))
  634. (and node (cons (node/k node) (node/v node))))))
  635. (set! wt-tree/rank
  636. (lambda (tree key)
  637. (guarantee-tree tree 'wt-tree/rank)
  638. ((tree-type/rank (tree/type tree)) tree key)))
  639. (set! wt-tree/min
  640. (lambda (tree)
  641. (guarantee-tree tree 'wt-tree/min)
  642. (node/k (node/min (tree/root tree)))))
  643. (set! wt-tree/min-datum
  644. (lambda (tree)
  645. (guarantee-tree tree 'wt-tree/min-datum)
  646. (node/v (node/min (tree/root tree)))))
  647. (set! wt-tree/min-pair
  648. (lambda (tree)
  649. (guarantee-tree tree 'wt-tree/min-pair)
  650. (let ((node (node/min (tree/root tree))))
  651. (cons (node/k node) (node/v node)))))
  652. (set! wt-tree/delete-min
  653. (lambda (tree)
  654. (guarantee-tree tree 'wt-tree/delete-min)
  655. (%make-wt-tree (tree/type tree)
  656. (node/delmin (tree/root tree)))))
  657. (set! wt-tree/delete-min!
  658. (lambda (tree)
  659. (guarantee-tree tree 'wt-tree/delete-min!)
  660. (set-tree/root! tree (node/delmin (tree/root tree)))))
  661. ;; < is a lexpr. Many compilers can open-code < so the lambda is faster
  662. ;; than passing <.
  663. (set! number-wt-type (local:make-wt-tree-type (lambda (u v) (< u v))))
  664. (set! string-wt-type (local:make-wt-tree-type string<?))
  665. 'done)
  666. ;;______________________________________________________________________________
  667. ;;
  668. ;; Test code, using maps from digit strings to the numbers they represent.
  669. ;;
  670. ;; (load-option 'wt-tree)
  671. ;;#|
  672. (define (test)
  673. (define (make-map lo hi step)
  674. (let loop ((i lo) (map (make-wt-tree string-wt-type)))
  675. (if (> i hi)
  676. map
  677. (loop (+ i step) (wt-tree/add map (number->string i) i)))))
  678. (define (wt-tree->alist t)
  679. (wt-tree/fold (lambda (key datum rest) (cons (cons key datum) rest)) '() t))
  680. (define (try-all operation trees)
  681. (map (lambda (t1)
  682. (map (lambda (t2)
  683. (operation t1 t2))
  684. trees))
  685. trees))
  686. (define (chunk tree)
  687. (let ((size (wt-tree/size tree)))
  688. (if (< size 8)
  689. size
  690. (let* ((midpoint (if (even? size)
  691. (/ size 2)
  692. (/ (+ size 1) 2)))
  693. (fulcrum (wt-tree/index tree midpoint)))
  694. (list (chunk (wt-tree/split< tree fulcrum))
  695. (list fulcrum)
  696. (chunk (wt-tree/split> tree fulcrum)))))))
  697. (define (verify name result expected)
  698. (newline)
  699. (display "Test ") (display name)
  700. (if (equal? result expected)
  701. (begin
  702. (display " passed"))
  703. (begin
  704. (display " unexpected result")
  705. (newline)
  706. (display "Expected: " expected)
  707. (newline)
  708. (display "Got: " result))))
  709. (let ((t1 (make-map 0 99 2)); 0,2,4,...,98
  710. (t2 (make-map 1 100 2)); 1,3,5,...,99
  711. (t3 (make-map 0 100 3))); 0,3,6,...,99
  712. (verify 'alist (wt-tree->alist t3);
  713. '(("0" . 0) ("12" . 12) ("15" . 15) ("18" . 18) ("21" . 21)
  714. ("24" . 24) ("27" . 27) ("3" . 3) ("30" . 30) ("33" . 33)
  715. ("36" . 36) ("39" . 39) ("42" . 42) ("45" . 45) ("48" . 48)
  716. ("51" . 51) ("54" . 54) ("57" . 57) ("6" . 6) ("60" . 60)
  717. ("63" . 63) ("66" . 66) ("69" . 69) ("72" . 72) ("75" . 75)
  718. ("78" . 78) ("81" . 81) ("84" . 84) ("87" . 87) ("9" . 9)
  719. ("90" . 90) ("93" . 93) ("96" . 96) ("99" . 99)))
  720. (verify 'union-sizes
  721. (try-all (lambda (t1 t2) (wt-tree/size (wt-tree/union t1 t2)))
  722. (list t1 t2 t3))
  723. '((50 100 67) (100 50 67) (67 67 34)))
  724. (verify 'difference-sizes
  725. (try-all (lambda (t1 t2)
  726. (wt-tree/size (wt-tree/difference t1 t2)))
  727. (list t1 t2 t3))
  728. '((0 50 33) (50 0 33) (17 17 0)))
  729. (verify 'intersection-sizes
  730. (try-all (lambda (t1 t2)
  731. (wt-tree/size (wt-tree/intersection t1 t2)))
  732. (list t1 t2 t3))
  733. '((50 0 17) (0 50 17) (17 17 34)))
  734. (verify 'equalities
  735. (try-all (lambda (t1 t2)
  736. (wt-tree/set-equal? (wt-tree/difference t1 t2)
  737. (wt-tree/difference t2 t1)))
  738. (list t1 t2 t3))
  739. '((#t #f #f) (#f #t #f) (#f #f #t)))
  740. (verify 'indexing
  741. (chunk (make-map 0 99 1))
  742. '((((7 ("15") 5) ("20") (6 ("27") 4)) ("31")
  743. ((6 ("38") 5) ("43") (6 ("5") 4)))
  744. ("54")
  745. (((7 ("61") 5) ("67") (6 ("73") 4)) ("78")
  746. ((6 ("84") 5) ("9") (5 ("95") 4)))))
  747. (newline)))
  748. ;;|#
  749. ;;; Local Variables:
  750. ;;; eval: (put 'with-n-node 'scheme-indent-function 1)
  751. ;;; eval: (put 'with-n-node 'scheme-indent-hook 1)
  752. ;;; End: