;; -*- Scheme -*-
;;
;; $Id: avl-tree01.scm,v 1.1 1998/03/16 07:57:14 foner Exp $

;;------------

(require 'avl-tree:nil?)
(require 'avl-tree::combine)
(require 'avl-tree::data)
(require 'avl-tree::left)
(require 'avl-tree::make)
(require 'avl-tree::right)

;;------------

;; procedure: avl-tree::add
;; arguments: tree key unwrap-key <? if-found if-not-found
;; signature: forall a,b,c
;;             => avl-tree[a,b,c]
;;              x a
;;              x (c -> a)
;;              x (a x a -> bool)
;;              x (avl-tree[a,b,c] -> avl-tree[a,b,c])
;;              x (() -> avl-tree[a,b,c])
;;             -> avl-tree[a,b,c]
;;
;; Locate the element with the given KEY in TREE.
;; UNWRAP-KEY is used to extract they portion of the ELEMENT that is
;; to be used as the key.  <? is used to compare two keys, it should
;; form a strict partial order over the type of KEY.
;; IF-FOUND is called with the part of the TREE where an element
;; containing KEY has been found.
;; IF-NOT-FOUND is called with the part of the TREE where the element
;; should be if it was in the tree.

(define avl-tree::add
  (lambda (t k uk <? if-found if-not-found)
      (let loop ((t t))
	(if (avl-tree:nil? t)
	    (if-not-found)
	    (let ((ck (uk (avl-tree::data t))))
	      (cond ((<? ck k)
		     (let ((n (loop (avl-tree::right t))))
		       (avl-tree::combine
			(avl-tree::left t)
			(avl-tree::data t)
			(avl-tree::left n)
			(avl-tree::data n)
			(avl-tree::right n))))
		    ((<? k ck)
		     (let ((n (loop (avl-tree::left t))))
		       (avl-tree::combine
			(avl-tree::left n)
			(avl-tree::data n)
			(avl-tree::right n)
			(avl-tree::data t)
			(avl-tree::right t))))
		    (else
		     (if-found t))))))))

;;-----------

;exports avl-tree::add

;; eof
