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