open import Equality open import Nat open import Bool open import Logic factorial : ℕ -> ℕ factorial zero = 1 factorial (succ n) = (succ n) * factorial n otherfunction : ℕ -> ℕ otherfunction zero = 1 otherfunction (succ n) = (succ n) * ih * ih where ih = otherfunction n otherfunction2 : ℕ -> ℕ otherfunction2 zero = 1 otherfunction2 (succ n) with otherfunction2 n otherfunction2 (succ n) | ih = (succ n) * ih * ih f : ℕ -> ℕ f zero = 1 f (succ n) with f n f (succ n) | zero = 2 f (succ n) | succ ih = 3 + n + ih is-even : ℕ -> Bool is-even zero = true is-even (succ n) with is-even n is-even (succ n) | true = false is-even (succ n) | false = true -- { false if is_even n = true -- is_even (succ n) = { -- { true otherwise -- The evenness predicate. data Even : ℕ -> Set where even-base : Even zero even-step : ∀ (n : ℕ) -> Even n -> Even (succ (succ n)) data Odd : ℕ -> Set where base-odd : Odd (succ zero) step-odd : ∀ (n : ℕ) -> Odd n -> Odd (succ (succ n)) lemma-even-or-odd : (n : ℕ) -> Even n ∨ Odd n lemma-even-or-odd zero = left even-base lemma-even-or-odd (succ zero) = right base-odd lemma-even-or-odd (succ (succ n)) with lemma-even-or-odd n lemma-even-or-odd (succ (succ n)) | left x = left (even-step n x) lemma-even-or-odd (succ (succ n)) | right x = right (step-odd n x) lemma-even-or-odd' : (n : ℕ) -> Even n ∨ Odd n lemma-even-or-odd' zero = left even-base lemma-even-or-odd' (succ zero) = right base-odd lemma-even-or-odd' (succ (succ n)) = lemma-even-or-odd-with n hypothesis where hypothesis = lemma-even-or-odd' n lemma-even-or-odd-with : (n : ℕ) -> Even n ∨ Odd n -> Even (succ (succ n)) ∨ Odd (succ (succ n)) lemma-even-or-odd-with n (left x) = left (even-step n x) lemma-even-or-odd-with n (right x) = right (step-odd n x) -- This theorem is known as "disjunction elimination" or "or elimination". orElim' : {A B C : Set} -> (A -> C) -> (B -> C) -> A ∨ B -> C orElim' = {!!} lemma-even-or-odd3 : (n : ℕ) -> Even n ∨ Odd n lemma-even-or-odd3 zero = left even-base lemma-even-or-odd3 (succ zero) = right base-odd lemma-even-or-odd3 (succ (succ n)) = orElim' (λ x → left (even-step n x)) (λ x → right (step-odd n x)) ih where ih = lemma-even-or-odd3 n -- ---------------------------------------------------------------------- -- * Rewrite lemma-mult-0 : ∀ (n : ℕ) -> n * zero == zero lemma-mult-0 zero = refl lemma-mult-0 (succ n) = equational n * zero + zero by context (λ x → x + zero) (lemma-mult-0 n) equals zero + zero by refl equals zero lemma-mult-0' : ∀ (n : ℕ) -> n * zero == zero lemma-mult-0' zero = refl lemma-mult-0' (succ n) rewrite (lemma-mult-0' n) = refl dist : ∀ (n m k : ℕ) -> (n + m) * k == n * k + m * k dist = {!!} assoc : ∀ (n m k : ℕ) -> (n + m) + k == n + (m + k) assoc = {!!} example : ∀ (n m k l : ℕ) -> Even ((n + m) * k + l) example n m k l rewrite (dist n m k) | assoc (n * k) (m * k) l = {!!} -- ---------------------------------------------------------------------- -- * Case split on implicit argument lemma-mult-0'' : ∀ {n : ℕ} {k : Bool} -> n * zero == zero lemma-mult-0'' {k = true} = {!!} lemma-mult-0'' {k = false} = {!!} -- ---------------------------------------------------------------------- -- * Pattern matching lambda -- There are two different ways to define a function: -- Named function: g : ℕ -> ℕ g n = n * n -- Unnamed function: h : ℕ -> ℕ h = (λ n → n * n) -- Advantage of named functions: -- * can use pattern matching (case distinctions) g1 : ℕ -> ℕ g1 zero = 15 g1 (succ n) = 3 * g1 n -- Advatange of lambda abstraction: -- * can use inside a nest expression -- Cannot do a case split inside a regular lambda abstraction. h1 : ℕ -> ℕ h1 = λ n -> {!!} -- There exists a notation that combines both advantages: -- * Can use inside a nested expression -- * Can do a case split -- "Pattern matching lambda" h2 : ℕ -> ℕ h2 = λ { zero → 15; (succ n) → 3 * h2 n } data Color : Set where red : Color blue : Color green : Color func : Color -> ℕ func = λ {red -> 0; red -> 6; blue -> 1; green -> 2} func' : Color -> ℕ func' red = 0 func' blue = 1 func' green = 2 and2 : Bool -> Bool -> Bool and2 true true = true and2 n m = false and4 : Bool -> Bool -> Bool -> Bool -> Bool and4 true true true true = true and4 n m k l = false -- { true if (n,m,k,l) = (true,true,true,true) -- f n m k l = { -- { false otherwise