module _ where open import eq open import nat open import nat-thms open import bool open import product open import product-thms open import bool-thms -- this may be useful, depending on how you do things open import list data BST : ℕ -> ℕ -> Set where leaf : ∀ {n m} -> n ≤ m ≡ tt -> BST n m node : ∀ {l' l u' u} -> (x : ℕ) -> BST l' x -> BST x u' -> l ≤ l' ≡ tt -> u' ≤ u ≡ tt -> BST l u {- some lemmas about max beyond what's in the IAL -} max-≤-1 : ∀ x i -> i ≤ x ≡ tt -> max x i ≤ x ≡ tt max-≤-1 zero zero i≤x = refl max-≤-1 (suc x) zero i≤x = ≤-refl (suc x) max-≤-1 (suc x) (suc i) i≤x rewrite max-suc x i = max-≤-1 x i i≤x max-lb1 : ∀ a b c -> a ≤ b ≡ tt -> a ≤ max b c ≡ tt max-lb1 zero b c a≤b = ≤0 (max b c) max-lb1 (suc a) (suc b) zero a≤b = a≤b max-lb1 (suc a) (suc b) (suc c) a≤b rewrite max-suc b c = suc≤ {a} {max b c} (max-lb1 a b c a≤b) -- this weakens the upper bound of a BST wub : ∀ l u u' -> u ≤ u' ≡ tt -> BST l u -> BST l u' wub l u u' u≤u' (leaf x) = leaf (≤-trans{l}{u}{u'} x u≤u') wub l u u' u≤u' (node{l'}{l}{u''}{u} x left right l≤l' u''≤u) = node{l'}{l}{u''}{u'} x left right l≤l' (≤-trans{u''}{u}{u'} u''≤u u≤u') -- this weakens the lower bound of a BST wlb : ∀ l l' u -> l' ≤ l ≡ tt -> BST l u -> BST l' u wlb l l' u l'≤l (leaf x) = leaf (≤-trans {l'} {l} {u} l'≤l x) wlb l l' u l'≤l (node{l''}{l}{u'}{u} x left right l≤l'' u'≤u) = node {l''} {l'} {u'} {u} x left right (≤-trans {l'} {l} {l''} l'≤l l≤l'') u'≤u {- 1. finish `insert` by filling in the missing pieces -} insert : ∀ {il iu} -> (i : ℕ) -> BST il iu -> BST (min il i) (max iu i) insert {il} {iu} i (leaf il≤iu) = node {min il i} {min il i} {max iu i} {max iu i} i (leaf (min-<1{il}{i})) (leaf (max-<2{iu}{i})) (≤-refl (min il i)) (≤-refl (max iu i)) insert {il} {iu} i (node x left right il≤l' u'≤iu) with keep (i ≤ x) insert {il} {iu} i (node {l'}{l}{u'}{u} x left right il≤l' u'≤iu) | tt , i≤x with insert i left ... | R = node {min l' i} {min il i} {u'} {max iu i} x (wub (min l' i) (max x i) x (max-≤-1 x i i≤x) R) right (min-mono1 il l' i il≤l') (max-lb1 u' iu i u'≤iu) insert {il} {iu} i (node {l'}{l}{u'}{u} x left right il≤l' u'≤iu) | ff , i≤x with insert i right ... | R = {!!} {- 2. Define a broken version of insert, called insertwrong that fails to rebuild the result tree when i ≤ x (but does it correctly in the other cases. -} insertwrong : ∀ {il iu} -> (i : ℕ) -> BST il iu -> BST (min il i) (max iu i) insertwrong = {!!} {- Here is what insertwrong would do on a BST that doesn't have the bounds. Your function have the same bug, but with the BST type. -} data SBST : Set where leaf : SBST node : ℕ -> SBST -> SBST -> SBST insertwrongSBST : ℕ -> SBST -> SBST insertwrongSBST i leaf = node i leaf leaf insertwrongSBST i (node x left right) with i ≤ x ... | tt = insertwrongSBST i left ... | ff = node x left (insertwrongSBST i right) {- this function definition captures the idea that a particular nat is in the tree -} _∈_ : ∀ {l u} -> ℕ -> BST l u -> 𝔹 x ∈ (leaf _) = ff x₂ ∈ (node x₁ left right _ _) = x₁ =ℕ x₂ || x₂ ∈ left || x₂ ∈ right {- 3. Ensure these test cases for insertwrong pass, demonstrating that insertwrong is, indeed, wrong. The holes should be filled with `refl` after insertwrong is finished -} _ : 1 ∈ (insertwrong 1 (leaf{0}{0} refl)) ≡ tt _ = {!!} --refl goes here _ : 1 ∈ (insertwrong 0 (insert 1 (leaf{0}{0} refl))) ≡ ff _ = {!!} --refl goes here _ : 1 ∈ (insertwrong 2 (insert 1 (leaf{0}{0} refl))) ≡ tt _ = {!!} --refl goes here {- 4. Using ∈, prove a result that won't hold for insertwrong called `ins-no-drop` -} {- these two lemmas are useful for proving `ins-no-drop` -} wub-∈ : ∀ l u u' u≤u' x b -> x ∈ (wub l u u' u≤u' b) ≡ x ∈ b wub-∈ l u u' u≤u' x (leaf _) = refl wub-∈ l u u' u≤u' x (node x₁ left right _ _) = refl wlb-∈ : ∀ l u u' u≤u' x b -> x ∈ (wlb l u u' u≤u' b) ≡ x ∈ b wlb-∈ l u u' u≤u' x (leaf _) = refl wlb-∈ l u u' u≤u' x (node x₁ left right _ _) = refl {- tip: at some point you'll want to use `with` to break out the two cases in `insert` inside the proof of `ins-no-drop`; when you do that, use with with exactly the same condition as in `insert`, namely `keep (i ≤ x) otherwise, agda may get upset and produce an error message ending with `the generated with function is well-formed`. -} ins-no-drop : ∀ {l u} (x i : ℕ) (b : BST l u) -> x ∈ b ≡ tt -> x ∈ (insert i b) ≡ tt ins-no-drop = {!!}