module _ where open import list open import nat open import nat-thms open import bool open import bool-thms open import eq open import product open import product-thms below : ℕ -> 𝕃 ℕ -> 𝕃 ℕ below x [] = [] below x₁ (x₂ :: l) with x₁ ≤ x₂ ... | tt = below x₁ l ... | ff = x₂ :: below x₁ l above : ℕ -> 𝕃 ℕ -> 𝕃 ℕ above x [] = [] above x₁ (x₂ :: l) with x₁ ≤ x₂ ... | tt = x₂ :: above x₁ l ... | ff = above x₁ l {- this is the basic quicksort algorithm. Agda cannot determine that it terminates. Rewrite it so that agda can tell (using the same technique we used in class for mergesort). Be sure to keep the same top-level signature and behavior so that the test cases below pass -} qs : 𝕃 ℕ -> 𝕃 ℕ qs [] = [] qs (x :: l) = qs (below x l) ++ (x :: []) ++ qs (above x l) {- test cases for qs; all should pass -} _ : qs [] ≡ [] _ = {! refl !} _ : qs (1 :: []) ≡ 1 :: [] _ = {! refl !} _ : qs (1 :: 2 :: []) ≡ 1 :: 2 :: [] _ = {! refl !} _ : qs (2 :: 1 :: []) ≡ 1 :: 2 :: [] _ = {! refl !} _ : qs (1 :: 2 :: 3 :: []) ≡ 1 :: 2 :: 3 :: [] _ = {! refl !} _ : qs (1 :: 3 :: 2 :: []) ≡ 1 :: 2 :: 3 :: [] _ = {! refl !} _ : qs (2 :: 1 :: 3 :: []) ≡ 1 :: 2 :: 3 :: [] _ = {! refl !} _ : qs (2 :: 3 :: 1 :: []) ≡ 1 :: 2 :: 3 :: [] _ = {! refl !} _ : qs (3 :: 1 :: 2 :: []) ≡ 1 :: 2 :: 3 :: [] _ = {! refl !} _ : qs (3 :: 2 :: 1 :: []) ≡ 1 :: 2 :: 3 :: [] _ = {! refl !} _ : qs (2 :: 1 :: 1 :: []) ≡ 1 :: 1 :: 2 :: [] _ = {! refl !} _ : qs (1 :: 2 :: 1 :: []) ≡ 1 :: 1 :: 2 :: [] _ = {! refl !} _ : qs (1 :: 1 :: 2 :: []) ≡ 1 :: 1 :: 2 :: [] _ = {! refl !} _ : qs (1 :: 1 :: 1 :: []) ≡ 1 :: 1 :: 1 :: [] _ = {! refl !} _ : qs (1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: []) ≡ 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: [] _ = {! refl !} _ : qs (8 :: 7 :: 6 :: 5 :: 4 :: 3 :: 2 :: 1 :: []) ≡ 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: [] _ = {! refl !} _ : qs (1 :: 3 :: 5 :: 7 :: 8 :: 6 :: 4 :: 2 :: []) ≡ 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: [] _ = {! refl !} data _∈_ : ℕ -> 𝕃 ℕ -> Set where here : ∀ x l -> x ∈ (x :: l) there : ∀ x y l -> x ∈ l -> x ∈ (y :: l) {- Lemma ideas: To prove these two results, I had to prove several lemmas: Three lemmas relating append (++) and list inclusion (∈): 1) if an element is in a list, I can append something to the end and the element is in that new list created by append 2) if an element is in a list, I can append something to the beginning and the element is in that new list created by append 3) if an element is in a list that is built from append, then it is either in the first argument to append or it is in the second argument to append. Three lemmas about inclusion, above, and below: 1) If an element is in a list, then it is in either the result of below on that list or the result of above on that list (assuming that the natural number argument to below and above are the same in both uses of above and below). 2,3) Proving the lemma in 1) uses two additional lemmas, one for below and one for above. One says that if an element is known to be in a list, and it is known to be below some number x, then it is in the result of below applied to x and to the list. Ditto, but with the comparsion the other way for above. -} -- You'll also probably need these two lemmas. They are a bit tricky -- at the agda level becuase of the way that the pattern matching and -- the where clause interact. ∈above : ∀ y x l -> y ∈ above x l -> y ∈ l ∈above y x (z :: l) y∈bel with x ≤ z ∈above .z x (z :: l) (here .z .(above x l)) | tt = here z l ∈above y x (z :: l) (there .y .z .(above x l) y∈bel) | tt = there y z l (∈above y x l y∈bel) ∈above y x (z :: l) y∈bel | ff = there y z l (∈above y x l y∈bel) ∈below : ∀ y x l -> y ∈ below x l -> y ∈ l ∈below y x (z :: l) y∈ab with x ≤ z ∈below y x (z :: l) y∈ab | tt = there y z l (∈below y x l y∈ab) ∈below .z x (z :: l) (here .z .(below x l)) | ff = here z l ∈below y x (z :: l) (there .y .z .(below x l) y∈ab) | ff = there y z l (∈below y x l y∈ab) -- Prove: quicksort doesn't drop any elements perm-⊂ : ∀ y l -> y ∈ l -> y ∈ qs l perm-⊂ y l x∈l = {!!} -- Prove: quicksort doesn't add any elements perm-⊃ : ∀ y l -> y ∈ qs l -> y ∈ l perm-⊃ y l x∈l = {!!}