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 open import sum smallest : ℕ -> 𝕃 ℕ -> ℕ smallest y [] = y smallest y (x :: l) = smallest (min x y) l rm : ℕ -> 𝕃 ℕ -> 𝕃 ℕ rm y [] = [] rm y (x :: l) = if x =ℕ y then l else x :: (rm y l) {- this is the basic selection sort algorithm. Agda cannot determine that it terminates. Rewrite it so that agda can tell (using the same technique we used in class for quicksort). Be sure to keep the same top-level signature and behavior so that the test cases below pass -} {- ss : 𝕃 ℕ -> 𝕃 ℕ ss [] = [] ss (x :: l) = smallest x l :: ss (rm (smallest x l) (x :: l)) -} ss : 𝕃 ℕ -> 𝕃 ℕ ss l = {!!} {- test cases for ms; all should pass -} _ : ss [] ≡ [] _ = refl _ : ss (1 :: []) ≡ 1 :: [] _ = refl _ : ss (1 :: 2 :: []) ≡ 1 :: 2 :: [] _ = refl _ : ss (2 :: 1 :: []) ≡ 1 :: 2 :: [] _ = refl _ : ss (1 :: 2 :: 3 :: []) ≡ 1 :: 2 :: 3 :: [] _ = refl _ : ss (1 :: 3 :: 2 :: []) ≡ 1 :: 2 :: 3 :: [] _ = refl _ : ss (2 :: 1 :: 3 :: []) ≡ 1 :: 2 :: 3 :: [] _ = refl _ : ss (2 :: 3 :: 1 :: []) ≡ 1 :: 2 :: 3 :: [] _ = refl _ : ss (3 :: 1 :: 2 :: []) ≡ 1 :: 2 :: 3 :: [] _ = refl _ : ss (3 :: 2 :: 1 :: []) ≡ 1 :: 2 :: 3 :: [] _ = refl _ : ss (2 :: 1 :: 1 :: []) ≡ 1 :: 1 :: 2 :: [] _ = refl _ : ss (1 :: 2 :: 1 :: []) ≡ 1 :: 1 :: 2 :: [] _ = refl _ : ss (1 :: 1 :: 2 :: []) ≡ 1 :: 1 :: 2 :: [] _ = refl _ : ss (1 :: 1 :: 1 :: []) ≡ 1 :: 1 :: 1 :: [] _ = refl _ : ss (1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: []) ≡ 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: [] _ = refl _ : ss (8 :: 7 :: 6 :: 5 :: 4 :: 3 :: 2 :: 1 :: []) ≡ 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: [] _ = refl _ : ss (1 :: 3 :: 5 :: 7 :: 8 :: 6 :: 4 :: 2 :: []) ≡ 1 :: 2 :: 3 :: 4 :: 5 :: 6 :: 7 :: 8 :: [] _ = refl {- Once you have proven that selection sort terminates for all inputs, prove that it sorts, according to this definition of what it means for a list to be sorted: -} data sorted : 𝕃 ℕ -> Set where zeroS : sorted [] oneS : ∀ x -> sorted (x :: []) manyS : ∀ x y l -> x ≤ y ≡ tt -> sorted (y :: l) -> sorted (x :: y :: l) sssorts : ∀ l -> sorted (ss l) sssorts l = {!!} {- A Suggestion: One good approach to proving that selection sort sorts is to start by just looking at what induction gives you. You should see something saying that you know that the recursive call that `ss` makes is sorted, and you have to show that `smallest x l` put on the front of that list is also sorted. This breaks down into a number of pieces, but two major ones to consider are to prove that `smallest x l` is smaller than everything in `x :: l` (smaller in the sense of ≤) and also that if something is smaller than everything in some list, then it is also smaller than everything in the sorted version of that list. Important in this approach to to come up with a definition that captures what it means for a number to be smaller than everything in a list, in a manner similar to the way that ∈ is defined (but that captures lower bound, not membership!). -}