Week 01 - Agda Exercises - Solutions
{-# OPTIONS --without-K --safe #-} module 01-Solutions where open import prelude hiding (not-is-involution)
Part I
_&&'_ : Bool → Bool → Bool true &&' true = true true &&' false = false false &&' true = false false &&' false = false _xor_ : Bool → Bool → Bool true xor true = false true xor false = true false xor true = true false xor false = false _^_ : ℕ → ℕ → ℕ n ^ zero = 1 n ^ suc m = n * (n ^ m) ^-example : 3 ^ 4 ≡ 81 ^-example = refl 81 _! : ℕ → ℕ zero ! = 1 suc n ! = suc n * (n !) !-example : 4 ! ≡ 24 !-example = refl 24 max : ℕ → ℕ → ℕ max zero m = m max (suc n) zero = suc n max (suc n) (suc m) = suc (max n m) min : ℕ → ℕ → ℕ min zero m = zero min (suc n) zero = zero min (suc n) (suc m) = suc (min n m) min-example : min 5 3 ≡ 3 min-example = refl 3 map : {X Y : Type} → (X → Y) → List X → List Y map f [] = [] map f (x :: xs) = f x :: map f xs map-example : map (_+ 3) (1 :: 2 :: 3 :: []) ≡ 4 :: 5 :: 6 :: [] map-example = refl _ filter : {X : Type} (p : X → Bool) → List X → List X filter {X} p [] = [] filter {X} p (x :: xs) = if (p x) then (x :: ys) else ys where ys : List X ys = filter p xs is-non-zero : ℕ → Bool is-non-zero zero = false is-non-zero (suc _) = true filter-example : filter is-non-zero (4 :: 3 :: 0 :: 1 :: 0 :: []) ≡ 4 :: 3 :: 1 :: [] filter-example = refl _
Part II
_≣_ : Bool → Bool → Type true ≣ true = 𝟙 true ≣ false = 𝟘 false ≣ true = 𝟘 false ≣ false = 𝟙 Bool-refl : (b : Bool) → b ≣ b Bool-refl true = ⋆ Bool-refl false = ⋆ ≡-to-≣ : (a b : Bool) → a ≡ b → a ≣ b ≡-to-≣ b b (refl b) = Bool-refl b ≣-to-≡ : (a b : Bool) → a ≣ b → a ≡ b ≣-to-≡ true true ⋆ = refl true ≣-to-≡ false false ⋆ = refl false
Part III
not-is-involution : (b : Bool) → not (not b) ≡ b not-is-involution true = refl true not-is-involution false = refl false ||-is-commutative : (a b : Bool) → a || b ≡ b || a ||-is-commutative true true = refl true ||-is-commutative true false = refl true ||-is-commutative false true = refl true ||-is-commutative false false = refl false &&-is-commutative : (a b : Bool) → a && b ≡ b && a &&-is-commutative true true = refl true &&-is-commutative true false = refl false &&-is-commutative false true = refl false &&-is-commutative false false = refl false -- Notice how we choose to pattern match on the leftmost argument, because -- that's also how we defined &&. &&-is-associative : (a b c : Bool) → a && (b && c) ≡ (a && b) && c &&-is-associative true b c = refl (b && c) &&-is-associative false b c = refl false -- Because &&' is defined by pattern matching on all its arguments, we now need -- to consider 2^3 = 8 cases. &&'-is-associative : (a b c : Bool) → a &&' (b &&' c) ≡ (a &&' b) &&' c &&'-is-associative true true true = refl true &&'-is-associative true true false = refl false &&'-is-associative true false true = refl false &&'-is-associative true false false = refl false &&'-is-associative false true true = refl false &&'-is-associative false true false = refl false &&'-is-associative false false true = refl false &&'-is-associative false false false = refl false max-is-commutative : (n m : ℕ) → max n m ≡ max m n max-is-commutative zero zero = refl zero max-is-commutative zero (suc m) = refl (suc m) max-is-commutative (suc n) zero = refl (suc n) max-is-commutative (suc n) (suc m) = to-show where IH : max n m ≡ max m n -- induction hypothesis IH = max-is-commutative n m -- recursive call on smaller arguments to-show : suc (max n m) ≡ suc (max m n) to-show = ap suc IH -- ap(ply) suc on both sides of the equation min-is-commutative : (n m : ℕ) → min n m ≡ min m n min-is-commutative zero zero = refl zero min-is-commutative zero (suc m) = refl zero min-is-commutative (suc n) zero = refl zero min-is-commutative (suc n) (suc m) = to-show where IH : min n m ≡ min m n -- induction hypothesis IH = min-is-commutative n m -- recursive call on smaller arguments to-show : suc (min n m) ≡ suc (min m n) to-show = ap suc IH -- ap(ply) suc on both sides of the equation 0-right-neutral : (n : ℕ) → n ≡ n + 0 0-right-neutral zero = refl zero 0-right-neutral (suc n) = to-show where IH : n ≡ n + 0 -- induction hypothesis IH = 0-right-neutral n -- recursive call on smaller argument to-show : suc n ≡ suc (n + 0) to-show = ap suc IH -- ap(ply) suc on both sides of the equation map-id : {X : Type} (xs : List X) → map id xs ≡ xs map-id [] = refl [] map-id (x :: xs) = to-show where IH : map id xs ≡ xs IH = map-id xs to-show : x :: map id xs ≡ x :: xs to-show = ap (x ::_) IH map-comp : {X Y Z : Type} (f : X → Y) (g : Y → Z) (xs : List X) → map (g ∘ f) xs ≡ map g (map f xs) map-comp f g [] = refl [] map-comp f g (x :: xs) = to-show where IH : map (g ∘ f) xs ≡ map g (map f xs) IH = map-comp f g xs to-show : g (f x) :: map (g ∘ f) xs ≡ g (f x) :: map g (map f xs) to-show = ap (g (f x) ::_) IH