open import bool open import eq open import sum {- The goal of this exercise is to write (and prove correct) a binary search tree insertion function. See below for more guidance. -} {- Here we import a type A, a comparison function on it and some basic properties of the comparison function, namely that it is total, reflexive, and transitive. Totality means that, for any two elements of A, either the first is smaller than the second, or the second is smaller than the first. Reflexivity means that an element is smaller than itself (justifying the use of the symbol ≤ instead of <). -} module _ (A : Set) (_≤A_ : A -> A -> 𝔹) (≤A-tot : (x : A) (y : A) -> (x ≤A y ≡ tt) ∨ (y ≤A x ≡ tt)) (≤A-refl : (x : A) -> x ≤A x ≡ tt) (≤A-trans : (x y z : A) -> x ≤A y ≡ tt -> y ≤A z ≡ tt -> x ≤A z ≡ tt) where open import nat {- min and max are defined just like those on natural numbers, but here they are defined on `A` -} minA : A -> A -> A minA x y = if x ≤A y then x else y maxA : A -> A -> A maxA x y = if x ≤A y then y else x {- this is an example proof that may be useful to you, demonstrating situations where totality of the ordering relation is helpful. -} minlbl : ∀ x y -> (minA x y) ≤A x ≡ tt minlbl x y with x ≤A y in eqn minlbl x y | tt = ≤A-refl x minlbl x y | ff with ≤A-tot x y minlbl x y | ff | inj₁ x≤y rewrite eqn with x≤y minlbl x y | ff | inj₁ x≤y | () minlbl x y | ff | inj₂ y≤x = y≤x {- the `bt` definition and `insbt` demonstrate the algorithm you're supposed to prove correct, but without the internal invariants that ensure that the function preseves the binary tree property. -} data bt : Set where leaf : bt node : A -> bt -> bt -> bt insbt : A -> bt -> bt insbt new leaf = node new leaf leaf insbt new (node root bt₁ bt₂) with new ≤A root insbt new (node root bt₁ bt₂) | tt = node root (insbt new bt₁) bt₂ insbt new (node root bt₁ bt₂) | ff = node root bt₁ (insbt new bt₂) {- the way to think about this is that `bst l u` is the type of binary search trees whose elements are bounded between `l` and `u` and, furthermore, these bounds are not tight (so it might be that the smallest number in the tree is larger than `l` and the largest is smaller than `u`). -} data bst : A -> A -> Set where leaf : ∀ {l u} -> {- here we just need to know the bounds are in order -} l ≤A u ≡ tt -> bst l u node : ∀ {l u l' u'} -> (d : A) -> {- Note that the value in this node, `d` itself becomes part of the bounds on the left and right subtrees. -} bst l' d -> bst d u' -> {- here we need to know that the bounds on the whole tree make sense, given the bounds on the left and right subtrees.-} l ≤A l' ≡ tt -> u' ≤A u ≡ tt -> bst l u {- your assignment is to finish `ins` using the same algorithm as `insbt` above, but working on binary searchtrees instead of just binary trees. In other words, under the assumtion that the input to the insertion algorithm is a binary search tree, prove that the result is too. -} ins : ∀ {l u} -> (d : A) -> bst l u -> bst (minA d l) (maxA d u) ins {l} {u} new bt = {!!}