{-
Last time:
- Agda as a programming language
- Agda as a proof language
This time: More on Agda as a proof language, i.e.:
- Recap
- Equational reasoning
- Disjunction (∨), existential quantification (∃), conjunction (∧)
- Well-founded recursion
And most importantly:
- Hands-on, supporting you with lots of exercises :-)
-}
data ℕ : Set where
zero : ℕ
succ : ℕ → ℕ
-- Inhabitants: zero, succ zero, succ (succ zero), succ (succ (succ zero)), ...
_+_ : ℕ → ℕ → ℕ
zero + y = y
succ x + y = succ (x + y)
{-
data _≡_ {X : Set} : X → X → Set where
refl : {x : X} → x ≡ x
cong : {X Y : Set} {a b : X} → (f : X → Y) → a ≡ b → f a ≡ f b
-- cong f refl = refl
cong {X} {Y} {a} {.a} f refl = refl
-- The pattern ".a" matches the contents of the variable "a" without introducing a new variable.
trans : {X : Set} {a b c : X} → a ≡ b → b ≡ c → a ≡ c
trans refl q = q
-}
open import Padova2025.ProvingBasics.Equality.Base
open import Padova2025.ProvingBasics.Equality.General
-- Logical reading: For all number y, it holds that y equals y + zero.
-- Computational reading: "+-zero" is a function which inputs a number y and which outputs
-- a witness that y equals y + zero.
+-zero : (y : ℕ) → y ≡ (y + zero)
+-zero zero = refl -- "This holds trivially, by a mere computation / by definition."
+-zero (succ y) = cong succ (+-zero y)
+-succ : (a b : ℕ) → succ (a + b) ≡ (a + succ b)
+-succ zero b = refl
+-succ (succ a) b = cong succ (+-succ a b)
open import Padova2025.ProvingBasics.Equality.Reasoning.Core
-- Logical reading: For all numbers x, for all numbers y, it holds that x + y equals y + x.
-- Computational reading: "+-comm" is a function which reads as input two numbers x and y,
-- and which outputs a witness that x + y equals y + x.
+-comm : (x : ℕ) → (y : ℕ) → (x + y) ≡ (y + x)
-- +-comm x y = refl
+-comm zero y = +-zero y
+-comm (succ a) y = trans (+-succ a y) (trans (+-comm a (succ y)) (+-succ y a))
-- A more beautiful way of writing down this proof is using "equational reasoning".
+-comm' : (a b : ℕ) → (a + b) ≡ (b + a)
+-comm' zero b = +-zero b
+-comm' (succ a) b = begin
succ a + b ≡⟨ refl ⟩
succ (a + b) ≡⟨ +-succ a b ⟩
a + succ b ≡⟨ +-comm' a (succ b) ⟩
succ (b + a) ≡⟨ +-succ b a ⟩
b + succ a ∎
+-comm'' : (a b : ℕ) → (a + b) ≡ (b + a)
+-comm'' zero b = +-zero b
+-comm'' (succ a) b = begin
succ a + b ≡⟨⟩
succ (a + b) ≡⟨ +-succ a b ⟩ -- \u{}
a + succ b ≡⟨ +-comm'' a (succ b) ⟩
succ (b + a) ≡⟨ +-succ b a ⟩
b + succ a ∎