#lang racket/base
(require "../lang/dracula.rkt" "../lang/check.rkt")
(provide (all-defined-out))
(begin-below
(in-package "ACL2")
(defun empty-tree? (tr) (not (consp tr)))
(defun height (tr) (if (empty-tree? tr) 0 (car tr)))
(defun key (tr) (cadr tr))
(defun data (tr) (caddr tr))
(defun left (tr) (cadddr tr))
(defun right (tr) (car (cddddr tr)))
(defun keys (tr)
(if (empty-tree? tr)
nil
(append (keys (left tr)) (list (key tr)) (keys (right tr)))))
(defun empty-tree ( ) nil)
(defun tree (k d lf rt)
(list (+ 1 (max (height lf) (height rt))) k d lf rt))
(defun key? (k) (rationalp k)) (defun key< (j k) (< j k)) (defun key> (j k) (key< k j))
(defun key= (j k) (and (not (key< j k)) (not (key> j k)))) (defun key-member (k ks)
(and (consp ks)
(or (key= k (car ks))
(key-member k (cdr ks)))))
(defun data? (d)
(if d t t))
(defun tree? (tr)
(or (empty-tree? tr)
(and (natp (height tr)) (= (height tr) (+ 1 (max (height (left tr))
(height (right tr)))))
(key? (key tr)) (data? (data tr)) (tree? (left tr)) (tree? (right tr)))))
(defun occurs-in-tree? (k tr)
(and (key? k)
(tree? tr)
(key-member k (keys tr))))
(defun alternate-occurs-in-tree? (k tr)
(and (key? k)
(tree? tr)
(not (empty-tree? tr))
(or (key= k (key tr))
(alternate-occurs-in-tree? k (left tr))
(alternate-occurs-in-tree? k (right tr)))))
(defun all-keys< (k ks)
(or (not (consp ks))
(and (key< (car ks) k) (all-keys< k (cdr ks)))))
(defun all-keys> (k ks)
(or (not (consp ks))
(and (key> (car ks) k) (all-keys> k (cdr ks)))))
(defun ordered? (tr)
(or (empty-tree? tr)
(and (tree? tr)
(all-keys< (key tr) (keys (left tr)))
(all-keys> (key tr) (keys (right tr)))
(ordered? (left tr))
(ordered? (right tr)))))
(defun balanced? (tr)
(and (tree? tr)
(or (empty-tree? tr)
(and (<= (abs (- (height (left tr)) (height (right tr)))) 1)
(balanced? (left tr))
(balanced? (right tr))))))
(defun avl-tree? (tr)
(and (ordered? tr)
(balanced? tr)))
(defun easy-R (tr)
(let* ((z (key tr)) (dz (data tr))
(zL (left tr)) (zR (right tr))
(x (key zL)) (dx (data zL))
(xL (left zL)) (xR (right zL)))
(tree x dx xL (tree z dz xR zR))))
(defun easy-L (tr)
(let* ((z (key tr)) (dz (data tr))
(zL (left tr)) (zR (right tr))
(x (key zR)) (dx (data zR))
(xL (left zR)) (xR (right zR)))
(tree x dx (tree z dz zL xL) xR)))
(defun left-heavy? (tr)
(and (tree? tr)
(not (empty-tree? tr))
(= (height (left tr)) (+ 2 (height (right tr))))))
(defun outside-left-heavy? (tr)
(and (left-heavy? tr)
(or (= (height (left (left tr)))
(height (right (left tr))))
(= (height (left (left tr)))
(+ 1 (height (right (left tr))))))))
(defun right-rotatable? (tr)
(and (ordered? tr)
(not (empty-tree? tr))
(balanced? (left tr))
(balanced? (right tr))
(not (empty-tree? (left tr)))))
(defun right-heavy? (tr)
(and (tree? tr)
(not (empty-tree? tr))
(= (height (right tr)) (+ 2 (height (left tr))))))
(defun outside-right-heavy? (tr)
(and (right-heavy? tr)
(or (= (height (right (right tr))) (height (left (right tr))))
(= (height (right (right tr))) (+ 1 (height (left (right tr))))))))
(defun left-rotatable? (tr)
(and (tree? tr)
(not (empty-tree? tr))
(balanced? (left tr))
(balanced? (right tr))
(not (empty-tree? (right tr)))))
(defun hard-R (tr)
(let* ((z (key tr))
(dz (data tr))
(zL (left tr))
(zR (right tr)))
(easy-R (tree z dz (easy-L zL) zR))))
(defun hard-L (tr)
(let* ((z (key tr))
(dz (data tr))
(zL (left tr))
(zR (right tr)))
(easy-L (tree z dz zL (easy-R zR)))))
(defun inside-left-heavy? (tr)
(and (left-heavy? tr)
(= (height (right (left tr)))
(+ 1 (height (left (left tr)))))))
(defun hard-R-rotatable? (tr)
(and (right-rotatable? tr)
(left-rotatable? (left tr))))
(defun inside-right-heavy? (tr)
(and (right-heavy? tr)
(= (height (left (right tr)))
(+ 1 (height (right (right tr)))))))
(defun hard-L-rotatable? (tr)
(and (left-rotatable? tr)
(right-rotatable? (right tr))))
(defun rot-R (tr)
(let ((zL (left tr)))
(if (< (height (left zL)) (height (right zL)))
(hard-R tr)
(easy-R tr))))
(defun rot-L (tr)
(let ((zR (right tr)))
(if (< (height (right zR)) (height (left zR)))
(hard-L tr)
(easy-L tr))))
(defun avl-insert (tr new-key new-datum)
(if (empty-tree? tr)
(tree new-key new-datum (empty-tree) (empty-tree))
(if (key< new-key (key tr))
(let* ((subL (avl-insert (left tr) new-key new-datum))
(subR (right tr))
(new-tr (tree (key tr) (data tr) subL subR)))
(if (= (height subL) (+ (height subR) 2))
(rot-R new-tr)
new-tr))
(if (key> new-key (key tr))
(let* ((subL (left tr))
(subR (avl-insert (right tr) new-key new-datum))
(new-tr (tree (key tr) (data tr) subL subR)))
(if (= (height subR) (+ (height subL) 2))
(rot-L new-tr)
new-tr))
(tree new-key new-datum (left tr) (right tr))))))
(defun easy-delete (tr)
(right tr))
(defun shrink (tr)
(if (empty-tree? (right tr))
(list (key tr) (data tr) (left tr))
(let* ((key-data-tree (shrink (right tr)))
(k (car key-data-tree))
(d (cadr key-data-tree))
(subL (left tr))
(subR (caddr key-data-tree))
(shrunken-tr (tree (key tr) (data tr) subL subR)))
(if (= (height subL) (+ 2 (height subR)))
(list k d (rot-R shrunken-tr))
(list k d shrunken-tr)))))
(defun raise-sacrum (tr)
(let* ((key-data-tree (shrink (left tr)))
(k (car key-data-tree))
(d (cadr key-data-tree))
(subL (caddr key-data-tree))
(subR (right tr))
(new-tr (tree k d subL subR)))
(if (= (height subR) (+ 2 (height subL)))
(rot-L new-tr)
new-tr)))
(defun delete-root (tr)
(if (empty-tree? (left tr))
(easy-delete tr)
(raise-sacrum tr)))
(defun avl-delete (tr k)
(if (empty-tree? tr)
tr
(if (key< k (key tr)) (let* ((new-left (avl-delete (left tr) k))
(new-tr (tree (key tr) (data tr) new-left (right tr))))
(if (= (height (right new-tr)) (+ 2 (height (left new-tr))))
(rot-L new-tr)
new-tr))
(if (key> k (key tr)) (let* ((new-right (avl-delete (right tr) k))
(new-tr (tree (key tr) (data tr) (left tr) new-right)))
(if (= (height (left new-tr)) (+ 2 (height (right new-tr))))
(rot-R new-tr)
new-tr))
(delete-root tr)))))
(defun avl-retrieve (tr k) (if (empty-tree? tr) nil (if (key< k (key tr))
(avl-retrieve (left tr) k) (if (key> k (key tr))
(avl-retrieve (right tr) k) (cons k (data tr))))))
(defun avl-flatten (tr) (if (empty-tree? tr) nil
(append (avl-flatten (left tr))
(list (cons (key tr) (data tr)))
(avl-flatten (right tr)))))
(defun occurs-in-pairs? (k pairs)
(and (consp pairs)
(or (key= k (caar pairs))
(occurs-in-pairs? k (cdr pairs)))))
(defun increasing-pairs? (pairs)
(or (not (consp (cdr pairs)))
(and (key< (caar pairs) (caadr pairs))
(increasing-pairs? (cdr pairs)))))
)