Lecture 11, July 12

The lecture notes I post serve two purposes: to remind you of the topics we discussed and to provide any interesting code examples I did during lecture. I would describe these notes as an outline, not a summary, of what I talked about during lecture. You are not expected to be able to learn the material simply from examining these notes, nor is reading these notes a reasonable substitute for attending lecture.

Trees

We spent most of lectur talking about trees. We also talked about make-predicate and assert.
#lang typed/racket

(require "../include/uchicago151.rkt")

(define-struct Point
  ([x : Real]
   [y : Real]))

(: f : (U Point Number) -> Number)
(define (f p)
  (cond
    [(Point? p) (Point-x p)]
    [else p]))

;(: g : Any -> Number)
;(define (g x)
;  (cond
;    [(number? x) (+ 4 x)]
;    [else (error "Non-number given to g")]))

(: g : Any -> Number)
(define (g x)
  (+ (assert x number?) 4))

(: h : Integer -> Integer)
(define (h x)
  (cond
    [(even? x) (assert (/ x 2) exact-integer?)]
    [else (+ 1 (* 3 x))]))
;(define (h x)
;  (cond
;    [(even? x) (/ x 2)]
;    [else (+ 1 (* 3 x))]))

;(cond
;  [(or (string=? "a" (string-first s))
;       (string=? "e" (string-first s))
;       (string=? "i" (string-first s))
;       ....

(define-type Vowel (U "a" "e" "i" "o" "u"))

(: e : String -> Vowel)
(define (e x)
  (cond
    [((make-predicate Vowel) x) x]
    [else (error "Input not vowel")]))

(define-type Expr (U Number Plus Times))
(define-struct Plus
  ([left : Expr]
   [right : Expr]))
(define-struct Times
  ([left : Expr]
   [right : Expr]))

(: evaluate : Expr -> Number)
(define (evaluate exp)
  (match exp
    [(? number?) exp]
    [(Plus l r) (+ (evaluate l) (evaluate r))]
    [(Times l r) (* (evaluate l) (evaluate r))]))

(: num-ops : Expr -> Nonnegative-Integer)
(define (num-ops exp)
  (match exp
    [(? number?) 0]
    [(Plus l r) (+ 1 (num-ops l) (num-ops r))]
    [(Times l r) (+ 1 (num-ops l) (num-ops r))]))

(define-struct Empty ())
(define-struct Num-Node
  ([value : Real]
   [lsub : Num-Tree]
   [rsub : Num-Tree]))
(define-type Num-Tree (U Empty Num-Node))

; Determines whether a real is in the tree or not
(: num-find : Real Num-Tree -> Boolean)
(define (num-find n t)
  (match t
    [(Empty) false]
    [(Num-Node v l r)
     (cond
       [(= n v) true]
       [(num-find n l) true]
       [(num-find n r) true]
       [else false])]))
;     (or (= n v)
;         (num-find n l)
;         (num-find n r))]))



(: test-tree Num-Tree)
(define test-tree
  (Num-Node 5
            (Num-Node 3 (Empty) (Empty))
            (Num-Node 7
                      (Empty)
                      (Num-Node 9
                                (Num-Node 8 (Empty) (Empty))
                                (Num-Node 10 (Empty) (Empty))))))

;(define-struct Empty ())
(define-struct (Node A)
  ([value : A]
   [lsub : (Tree A)]
   [rsub : (Tree A)]))
(define-type (Tree A) (U Empty (Node A)))



(: bst-insert : Real Num-Tree -> Num-Tree)
(define (bst-insert n t)
  (match t
    [(Empty) (Num-Node n (Empty) (Empty))]
    [(Num-Node v l r)
     (cond
       [(= n v) t]
       [(< n v) (Num-Node v (bst-insert n l) r)]
       [else (Num-Node v l (bst-insert n r))])]))

(: insert : (All (A) (A A -> Boolean) A (Tree A) -> (Tree A)))
(define (insert f n t)
  (match t
    [(Empty) (Node n (Empty) (Empty))]
    [(Node v l r)
     (cond
       [(equal? n v) t]
       [(f n v) (Node v (insert f n l) r)]
       [else (Node v l (insert f n r))])]))

;(foldl (λ ([n : Real] [t : (Tree Real)]) (insert < n t)) (Empty) '(4 3 6 1))

(: bst-find : Real Num-Tree -> Boolean)
(define (bst-find n t)
  (match t
    [(Empty) false]
    [(Num-Node v l r)
     (cond
       [(= n v) true]
       [(< n v) (bst-find n l)]
       [else (bst-find n r)])]))

(: find : (All (A) (A A -> Boolean) A (Tree A) -> Boolean))
(define (find f n t)
  (match t
    [(Empty) false]
    [(Node v l r)
     (cond
       [(equal? n v) true]
       [(f n v) (find f n l)]
       [else (find f n r)])]))

(: inorder : (All (A) (Tree A) -> (Listof A)))
(define (inorder t)
  (match t
    [(Empty) '()]
    [(Node v l r) (append (inorder l)
                          (append (list v)
                                  (inorder r)))]))

(: preorder : (All (A) (Tree A) -> (Listof A)))
(define (preorder t)
  (match t
    [(Empty) '()]
    [(Node v l r) (append (list v)
                          (append (preorder l)
                                  (preorder r)))]))

(: sum-tree : (Tree Number) -> Number)
(define (sum-tree t)
  (match t
    [(Empty) 0]
    [(Node v l r) (+ v (sum-tree l) (sum-tree r))])) ; pre-order traversal

(: str-app-tree : (Tree String) -> String)
(define (str-app-tree t)
  (match t
    [(Empty) ""]
    [(Node v l r) (string-append (str-app-tree l)
                                 (str-app-tree r)
                                 v)]))

(str-app-tree (Node "Hi"
                    (Node "Cat" (Empty) (Empty))
                    (Node "Dog" (Empty) (Empty))))

(define-struct (3-Node A)
  ([v : A]
   [l : (3-Tree A)]
   [m : (3-Tree A)]
   [r : (3-Tree A)]))
(define-type (3-Tree A) (U Empty (3-Node A)))

(define-struct (Variable-Node A)
  ([v : A]
   [children : (Listof (Variable-Tree A))]))
(define-type (Variable-Tree A) (U Empty (Variable-Node A)))

(: count : (All (A) (Variable-Tree A) -> Nonnegative-Integer))
(define (count t)
  (match t
    [(Empty) 0]
    [(Variable-Node _ chldrn) (+ 1 (foldl + 0 (map (inst count A) chldrn)))]))