73 lines
2.4 KiB
Agda
73 lines
2.4 KiB
Agda
module add-assoc where
|
||
|
||
open import Data.Nat using (ℕ; zero; suc; _+_)
|
||
open import Relation.Binary.PropositionalEquality using (_≡_; refl; cong)
|
||
|
||
|
||
-- `+-assoc` is an identifier like `add-assoc`. Nothing special
|
||
+-assoc : Set
|
||
+-assoc = ∀ (a b c : ℕ) → a + (b + c) ≡ (a + b) + c -- enunciation
|
||
|
||
{- DOUBT:
|
||
Why is this not type checking?
|
||
|
||
+-assoc = ∀ (a b c : ℕ) → a + (b + c) → (a + b) + c -- enunciation
|
||
|
||
-}
|
||
|
||
-- an object of this type is the proof
|
||
+-assoc-proof : ∀ (a b c : ℕ) → a + (b + c) ≡ (a + b) + c
|
||
+-assoc-proof zero b c = refl
|
||
+-assoc-proof (suc a) b c = cong suc (+-assoc-proof a b c) -- generated from doing case-split on 'a'
|
||
-- agda assigns a unique id to each hole
|
||
-- C-c C-, (comma) to get info about hole under cursor
|
||
-- For the above hole, it shows:
|
||
--
|
||
-- Goal: a + (b + c) ≡ a + b + c
|
||
-- ————————————————————————————————————————————————————————————
|
||
-- c : ℕ
|
||
-- b : ℕ
|
||
-- a : ℕ
|
||
--
|
||
-- `(a + b) + c` is shown as `a + b + c` as `+` is left associative.
|
||
-- So both are same.
|
||
|
||
{- Doing case split -}
|
||
-- With cursor on the hole, press: C-c C-c
|
||
-- It will ask name of variable to do case split on.
|
||
-- We say 'a', here.
|
||
-- Initial clause will be replaced by two new ones
|
||
--
|
||
-- > +-assoc-proof zero b c = {!!} -- a replaced by zero
|
||
-- > +-assoc-proof (suc a) b c = {!!} -- a replaced by (suc a)
|
||
--
|
||
-- doing refl (by C-c C-r) finishes first case
|
||
--
|
||
-- Doing C-c C-, on remaining goal says:
|
||
-- >
|
||
-- > Goal: suc (a + (b + c)) ≡ suc (a + b + c)
|
||
-- > ————————————————————————————————————————————————————————————
|
||
-- > c : ℕ
|
||
-- > b : ℕ
|
||
-- > a : ℕ
|
||
-- >
|
||
--
|
||
-- The cong function handles cases where goal is like
|
||
-- f(arg1) ≡ f(arg2)
|
||
-- in which case we only have to show that arg1 ≡ arg2
|
||
-- congruence of equality
|
||
--
|
||
-- we _write_ `cong suc` inside the remaining hole and do a `refl` with C-c C-r
|
||
-- to get this goal:
|
||
--
|
||
-- > ?2 : a + (b + c) ≡ a + b + c
|
||
--
|
||
-- A recursive call to `+-assoc-proof` can finish this off.
|
||
-- Write `+-assoc-proof a b c` into the last hole
|
||
-- and solve it with C-c C-space
|
||
--
|
||
-- So the final proof is:
|
||
--
|
||
-- +-assoc-proof zero b c = refl
|
||
-- +-assoc-proof (suc a) b c = cong suc (+-assoc-proof a b c) -- generated from doing case-split on 'a'
|