6.8. Exercises
Define each function and prove each law in Lean, replacing sorry. Download the exercise file Lecture06.lean and open it in VS Code. Each type is given; your task is the functions and the proofs. The laws here are settled by rfl or decide on closed values, since the proofs by induction belong to Lecture 7. Exercises 9 and 10 are optional.
Exercise 1. Define turnRight on the four compass directions, and prove by decide that turning right four times returns north.
namespace FuncEx
inductive Direction where
| north | east | south | west
deriving DecidableEq
def turnRight : Direction → Direction :=
sorry
theorem turn_four :
turnRight (turnRight (turnRight
(turnRight Direction.north))) = Direction.north :=
sorry
end FuncEx
Exercise 2. Define lastOpt, the last element of a list as an option, and prove its value on the empty list and on a concrete list.
namespace FuncEx
def lastOpt {α : Type} : List α → Option α :=
sorry
theorem last_opt_nil {α : Type} :
lastOpt ([] : List α) = none :=
sorry
theorem last_opt_example :
lastOpt [3, 1, 4] = some 4 :=
sorry
end FuncEx
Exercise 3. Define the area of a rectangle and prove a concrete area.
namespace FuncEx
structure Rectangle where
width : ℕ
height : ℕ
def area (r : Rectangle) : ℕ :=
sorry
theorem area_example :
area { width := 3, height := 4 } = 12 :=
sorry
end FuncEx
Exercise 4. Extend the rectangle to a box with a depth, and define its volume from the inherited fields.
namespace FuncExBox
structure Rectangle where
width : ℕ
height : ℕ
structure Box extends Rectangle where
depth : ℕ
def volume (b : Box) : ℕ :=
sorry
theorem volume_example :
volume { width := 2, height := 3, depth := 4 } = 24 :=
sorry
end FuncExBox
Exercise 5. Complete the Doubler instances, doubling a number by addition and a list by self-append, and the selector, then prove the doubled value for ℕ.
namespace FuncEx
class Doubler (α : Type) where
dup : α → α
instance : Doubler ℕ :=
sorry
instance {α : Type} : Doubler (List α) :=
sorry
def applyDup {α : Type} [Doubler α] (a : α) : α :=
sorry
theorem dup_nat : applyDup (3 : ℕ) = 6 :=
sorry
end FuncEx
Exercise 6. Count the leaves and the branches of a binary tree, and check the relation between them on a concrete tree.
namespace FuncEx
inductive Tree (α : Type) where
| leaf
| branch (l : Tree α) (x : α) (r : Tree α)
def leaves {α : Type} : Tree α → ℕ :=
sorry
def nodes {α : Type} : Tree α → ℕ :=
sorry
def tx : Tree ℕ :=
.branch (.branch .leaf 1 .leaf) 2 .leaf
theorem leaves_nodes : leaves tx = nodes tx + 1 :=
sorry
end FuncEx
Exercise 7. Define replicate, the list of n copies of a value, and prove its value at 0.
namespace FuncEx
def replicate {α : Type} : ℕ → α → List α :=
sorry
theorem replicate_zero {α : Type} (x : α) :
replicate 0 x = [] :=
sorry
end FuncEx
Exercise 8. Define isEmpty by a match, and prove its two computational laws.
namespace FuncEx
def isEmpty {α : Type} : List α → Bool :=
sorry
theorem is_empty_nil {α : Type} :
isEmpty ([] : List α) = true :=
sorry
theorem is_empty_cons {α : Type} (x : α)
(xs : List α) : isEmpty (x :: xs) = false :=
sorry
end FuncEx
Exercise 9. Optional. A rose tree branches into a list of subtrees. Define rsize, the number of its nodes, noting the nested recursion through List.
namespace FuncEx
inductive Rose (α : Type) where
| node (x : α) (children : List (Rose α))
def rsize {α : Type} : Rose α → ℕ :=
sorry
end FuncEx
Exercise 10. Optional. A length-indexed vector rules out the empty case in its type. Define the total head of a nonempty vector and evaluate it.
namespace FuncEx
inductive Vec (α : Type) : ℕ → Type where
| nil : Vec α 0
| cons {n : ℕ} : α → Vec α n → Vec α (n + 1)
def vhead {α : Type} {n : ℕ} : Vec α (n + 1) → α :=
sorry
def vx : Vec ℕ 2 := .cons 3 (.cons 4 .nil)
end FuncEx