agda学习笔记---证明加法交换律和结合律
真的一切推倒重来啊
总之所有的证明基于加法的定义
等式
begin
起始
==< 依据 >
...
结论
\qed
cong : x == y -> f x == f y
cong-app : \forall x f == g -> f x == g x
sym x== y -> y == x
import Relation.Binary.PropositionalEquality as Eq
open Eq using (_≡_; refl; cong; sym)
open Eq.≡-Reasoning using (begin_; _≡⟨⟩_; step-≡; _∎)
data ℕ : Set where
zero : ℕ
suc : ℕ → ℕ
--add
_+_ : ℕ → ℕ → ℕ
zero + m = m
suc n + m = suc (n + m)
--multiply
_*_ : ℕ → ℕ → ℕ
zero * m = zero
suc n * m = (n * m) + m
--proof:
+-assoc : ∀ (m n p : ℕ) → (m + n) + p ≡ m + (n + p)
+-assoc zero n p =
begin
(zero + n) + p
≡⟨⟩
n + p
≡⟨⟩
zero + (n + p)
∎
+-assoc (suc m) n p =
begin
(suc m + n) + p
≡⟨⟩
suc (m + n) + p
≡⟨⟩
suc ((m + n) + p)
≡⟨ cong suc (+-assoc m n p) ⟩
suc (m + (n + p))
≡⟨⟩
suc m + (n + p)
∎
+-identityr : ∀ (m : ℕ) → m + zero ≡ m
+-identityr zero = refl
+-identityr (suc m) =
begin
suc m + zero
≡⟨⟩
suc (m + zero)
≡⟨ cong suc (+-identityr m) ⟩
suc m
∎
+-suc : ∀ (n m : ℕ) → n + suc m ≡ suc (n + m)
+-suc zero m =
begin
zero + suc m
≡⟨⟩
suc m
≡⟨⟩
suc (zero + m)
∎
+-suc (suc n) m =
begin
suc n + suc m
≡⟨⟩
suc (n + suc m)
≡⟨ cong suc (+-suc n m) ⟩
suc (suc (n + m))
≡⟨⟩
suc (suc n + m)
∎
+-comm : ∀ (n m : ℕ) → n + m ≡ m + n
+-comm m zero =
begin
m + zero
≡⟨ +-identityr m ⟩
m
≡⟨⟩
zero + m
∎
+-comm m (suc n) =
begin
m + suc n
≡⟨ +-suc m n ⟩
suc (m + n)
≡⟨ cong suc (+-comm m n) ⟩
suc (n + m)
≡⟨⟩
suc n + m
∎
这是对加法交换律和结合率的证明
证明交换率的时候需要先证明两个引理:
① : 0 是加法的右幺元
②: m + suc n = suc (m + n)
小练习
--practice
+-swap : ∀ (m n p : ℕ) → (m + n) + p ≡ n + (m + p)
+-swap zero n p = refl
+-swap (suc m) n p =
begin
((suc m + n) + p)
≡⟨⟩
suc (m + n) + p
≡⟨⟩
suc ((m + n) + p)
≡⟨ cong suc (+-swap m n p) ⟩
suc (n + (m + p))
≡⟨ cong suc (+-comm n (m + p)) ⟩
suc ((m + p) + n)
≡⟨⟩
suc (m + p) + n
≡⟨ +-comm (suc (m + p)) n ⟩
n + suc (m + p)
≡⟨⟩
n + (suc m + p)
∎
agda真的严格的半死
只要不是定义就必须要写依据
rewrite
+-swap' : ∀ (m n p : ℕ) → (m + n) + p ≡ n + (m + p)
+-swap' zero n p = refl
+-swap' (suc m) n p rewrite +-swap' m n p | +-comm n (m + p) | +-comm n (suc (m + p)) = refl
用 rewrite 来改写!
rewrite 后面的用 | 隔开, 证明顺序从左到右
crtl + c ctrl + l : load
ctrl + c ctrl + c :填入变量
ctrl + c ctrl + , :显示goal
ctrl +c ctrl + a : 自动填充
有点酷啊