|
1 | | -def hello := "world" |
| 1 | +variable (p q r : Prop) |
| 2 | +set_option linter.unusedVariables false |
| 3 | + |
| 4 | +-- commutativity of ∧ and ∨ |
| 5 | +example : p ∧ q ↔ q ∧ p := |
| 6 | + Iff.intro |
| 7 | + (fun (h: p ∧ q) => And.intro h.right h.left) |
| 8 | + (fun (h: q ∧ p) => And.intro h.right h.left) |
| 9 | + |
| 10 | +-- other properties |
| 11 | +example : (p → (q → r)) ↔ (p ∧ q → r) := |
| 12 | + Iff.intro |
| 13 | + (fun (hpqr : p → q → r) => fun (hpq : p ∧ q) => (hpqr hpq.left) hpq.right ) |
| 14 | + (fun hpqr : p ∧ q → r => fun (hp : p) => fun (hq : q) => hpqr ⟨ hp, hq ⟩ ) |
| 15 | + |
| 16 | +example : ¬(p ∧ ¬p) := |
| 17 | + fun hpnp : p ∧ ¬p => |
| 18 | + show False from hpnp.right hpnp.left |
| 19 | + |
| 20 | +example : (p → q) → (¬q → ¬p) := |
| 21 | + fun hpq : p → q => |
| 22 | + fun hnq : ¬ q => |
| 23 | + fun hp : p => |
| 24 | + show False from hnq (hpq hp) |
| 25 | + |
| 26 | + |
| 27 | +section |
| 28 | + |
| 29 | + open Classical |
| 30 | + |
| 31 | + example : ¬(p ∧ q) → ¬p ∨ ¬q := |
| 32 | + fun hnpq : ¬(p ∧ q) => |
| 33 | + byCases |
| 34 | + (fun hp : p => |
| 35 | + byCases |
| 36 | + (fun hq : q => show ¬p ∨ ¬q from False.elim (hnpq ⟨hp, hq⟩)) |
| 37 | + Or.inr ) |
| 38 | + Or.inl |
| 39 | + |
| 40 | + example : (((p → q) → p) → p) := |
| 41 | + fun hpqp : (p → q) → p => |
| 42 | + Or.elim (em p) |
| 43 | + (id) |
| 44 | + (fun hnp : ¬p => |
| 45 | + have hpq : p → q := fun hp : p => absurd hp hnp |
| 46 | + show p from hpqp hpq |
| 47 | + ) |
| 48 | + |
| 49 | +end |
| 50 | + |
| 51 | + |
| 52 | +variable (α : Type) (p q : α → Prop) |
| 53 | + |
| 54 | +example : (∃ x : α, r) → r := |
| 55 | + fun h : (∃ x : α, r) => Exists.elim h (fun a : α => id) |
| 56 | + |
| 57 | +section |
| 58 | + open Classical |
| 59 | + |
| 60 | + example : (x : α) → ∃ y : α, (p y → ∀ z : α, p z) := |
| 61 | + fun x : α => |
| 62 | + byCases |
| 63 | + (fun hd : (∀ z : α, p z) => ⟨ x, fun _ => hd ⟩ ) |
| 64 | + (fun hnd : ¬(∀ z : α, p z) => |
| 65 | + suffices ey : (∃ y : α, ¬ p y) |
| 66 | + from Exists.elim ey |
| 67 | + (λ y => λ hnpy => ⟨ y, λ hpy => show ∀ z : α, p z from False.elim (hnpy hpy) ⟩ ) |
| 68 | + byContradiction λ hney : ¬(∃ y : α, ¬ p y) => |
| 69 | + hnd (λ z : α => byContradiction λ hpz : ¬ p z => hney ⟨ z, hpz ⟩ ) ) |
| 70 | + |
| 71 | +end |
| 72 | + |
| 73 | +section |
| 74 | + |
| 75 | +variable (men : Type) (barber : men) |
| 76 | +variable (shaves : men → men → Prop) |
| 77 | + |
| 78 | +example (h : ∀ x : men, shaves barber x ↔ ¬ shaves x x) : False := |
| 79 | + have hb : shaves barber barber ↔ ¬ shaves barber barber := h barber |
| 80 | + suffices np : ¬ shaves barber barber from np (hb.mpr np) |
| 81 | + fun p : shaves barber barber => (hb.mp p) p |
| 82 | + |
| 83 | +end |
| 84 | + |
| 85 | +def divs (m n : Nat) : Prop := ∃ k : Nat, m*k = n |
| 86 | + |
| 87 | +def irred (n : Nat) : Prop := ∀ m : Nat, divs m n → (m = 1 ∨ m = n) |
| 88 | + |
| 89 | +def prime (n : Nat) : Prop := n > 1 ∧ ∀ (a b : Nat), divs n (a*b) → (divs n a ∨ divs n b) |
| 90 | + |
| 91 | +theorem zero_or_succ (n : Nat) : n = 0 ∨ ∃ l : Nat, n = l.succ := |
| 92 | + match n with |
| 93 | + | Nat.zero => Or.inl rfl |
| 94 | + | Nat.succ l => Or.inr ⟨ l, rfl ⟩ |
| 95 | + |
| 96 | +theorem le_add (n m : Nat) : n ≤ n+m := |
| 97 | + match m with |
| 98 | + | Nat.zero => calc |
| 99 | + n ≤ n := Nat.le_refl n |
| 100 | + n = n + Nat.zero := rfl |
| 101 | + | Nat.succ l => calc |
| 102 | + n ≤ n+l := le_add n l |
| 103 | + n+l ≤ (n+l).succ := Nat.le_succ (n+l) |
| 104 | + (n+l).succ = n+l.succ := Eq.symm (Nat.add_succ n l) |
| 105 | + |
| 106 | +theorem le_mul (n k : Nat) : (0 < k) → n ≤ n*k := |
| 107 | + λ hk : 0<k => match k with |
| 108 | + | 0 => absurd hk (Nat.not_lt_zero 0) |
| 109 | + | Nat.succ l => calc |
| 110 | + n <= n + (n*l) := le_add n (n*l) |
| 111 | + n + (n*l) = n*1 + n*l := by simp |
| 112 | + n*1 + n*l = n*(l+1) := by rw [Nat.add_comm l 1, Nat.mul_add n 1 l] |
| 113 | + |
| 114 | +theorem nats_integral (n m : Nat) : 0 < n*m → 0 < n := |
| 115 | + match n with |
| 116 | + | 0 => |
| 117 | + λ hnm : 0 < 0*m => |
| 118 | + have con : 0 < 0 := calc |
| 119 | + 0 < 0*m := hnm |
| 120 | + 0*m = 0 := by simp |
| 121 | + absurd con (Nat.lt_irrefl 0) |
| 122 | + | Nat.succ l => (λ hnm : 0 < (l.succ)*m => Nat.zero_lt_succ l) |
| 123 | + |
| 124 | +theorem divs_zero (n : Nat) : divs 0 n → 0=n := |
| 125 | + λ ⟨k, h0kn⟩ => calc |
| 126 | + 0 = 0*k := by simp |
| 127 | + 0*k = n := h0kn |
| 128 | + |
| 129 | +theorem divs_le (m n : Nat) : n>0 → divs m n → m ≤ n := |
| 130 | + λ hn => |
| 131 | + λ ⟨k, hmkn⟩ => |
| 132 | + have hkm : 0 < k*m := calc |
| 133 | + 0 < n := hn |
| 134 | + n = m*k := Eq.symm hmkn |
| 135 | + m*k = k*m := Nat.mul_comm m k |
| 136 | + calc |
| 137 | + m <= m*k := le_mul m k (nats_integral k m hkm) |
| 138 | + m*k = n := hmkn |
| 139 | + |
| 140 | +theorem le_irre (m n : Nat) (hmn : m ≤ n) (hnm : n ≤ m) : m=n := |
| 141 | + have hor : m=n ∨ m < n := Nat.eq_or_lt_of_le hmn |
| 142 | + Or.elim hor |
| 143 | + (id) |
| 144 | + (λ mltn => |
| 145 | + have nltn : n < n := calc |
| 146 | + n ≤ m := hnm |
| 147 | + m < n := mltn |
| 148 | + absurd nltn (Nat.lt_irrefl n)) |
| 149 | + |
| 150 | +theorem antisymm_divs (m n : Nat) : divs m n ∧ divs n m → m = n := |
| 151 | + λ ⟨ hmn, hnm ⟩ => |
| 152 | + match m with |
| 153 | + | 0 => divs_zero n hmn |
| 154 | + | Nat.succ m₁ => |
| 155 | + let ⟨k, (hk : n*k = m₁+1)⟩ := hnm |
| 156 | + have npos: n>0 := nats_integral n k (calc |
| 157 | + 0 < m₁+1 := Nat.succ_pos m₁ |
| 158 | + m₁+1 = n*k := Eq.symm hk) |
| 159 | + have mlen : m₁+1 ≤ n := divs_le (m₁+1) n npos hmn |
| 160 | + have nlem : n ≤ m₁+1 := divs_le n (m₁+1) (Nat.succ_pos m₁) hnm |
| 161 | + (le_irre (m₁+1) n mlen nlem) |
| 162 | + |
| 163 | +theorem one_divs (n : Nat) : divs 1 n := ⟨ n, Nat.one_mul n ⟩ |
| 164 | + |
| 165 | +theorem right_cancel_mul (m n k : Nat) (npos : n>0) (h : m*n = k*n) : m=k := |
| 166 | + have tric := Nat.lt_trichotomy m k |
| 167 | + by |
| 168 | + apply Or.elim tric |
| 169 | + . intro mltk |
| 170 | + have mnltkn := (@Nat.mul_lt_mul_right n m k npos).mpr mltk |
| 171 | + rw [←h] at mnltkn |
| 172 | + exact False.elim ((Nat.lt_irrefl (m*n)) mnltkn) |
| 173 | + . intro dic |
| 174 | + apply Or.elim dic |
| 175 | + . exact id |
| 176 | + . intro kltm |
| 177 | + have knltmn := (@Nat.mul_lt_mul_right n k m npos).mpr kltm |
| 178 | + rw [←h] at knltmn |
| 179 | + exact False.elim ((Nat.lt_irrefl (m*n)) knltmn) |
| 180 | + |
| 181 | + |
| 182 | +theorem primes_are_irred (n : Nat) : prime n → irred n := |
| 183 | + λ hn : prime n => |
| 184 | + -- have ng1 : n > 1 := hn.left |
| 185 | + have npos : 0 < n := calc |
| 186 | + 0 < 1 := Nat.zero_lt_succ 0 |
| 187 | + 1 < n := hn.left |
| 188 | + λ m : Nat => |
| 189 | + λ ⟨ k, hk ⟩ => |
| 190 | + have hndiv : divs n (m*k) := ⟨ 1, Eq.trans (Nat.mul_one n) (Eq.symm hk) ⟩ |
| 191 | + have hdivor : divs n m ∨ divs n k := hn.right m k hndiv |
| 192 | + Or.elim hdivor |
| 193 | + (λ ndivm => (Or.inr (antisymm_divs m n ⟨ ⟨k, hk ⟩, ndivm ⟩)) ) |
| 194 | + (λ ⟨ j, (hj : n*j=k) ⟩ => |
| 195 | + have h : 1*n = m*j*n := calc |
| 196 | + 1*n = n := Nat.one_mul n |
| 197 | + n = m*(n*j) := by rw [hj, hk] |
| 198 | + m*(n*j) = m*j*n := by rw [Nat.mul_comm n j, Nat.mul_assoc m j n] |
| 199 | + have mj1 : m*j=1 := right_cancel_mul (m*j) n 1 npos (Eq.symm h) |
| 200 | + have mdiv1 : divs m 1 := ⟨ j ,mj1 ⟩ |
| 201 | + show m=1 ∨ m=n from Or.inl (antisymm_divs m 1 ⟨ mdiv1, one_divs m ⟩ )) |
| 202 | + |
| 203 | +section |
| 204 | +variable (p q r s : Prop) |
| 205 | + |
| 206 | +example : s ∧ q ∧ r → p ∧ r → q ∧ p := by |
| 207 | + intro ⟨_, ⟨hq, _⟩⟩ ⟨hp, _⟩ |
| 208 | + exact ⟨hq, hp⟩ |
| 209 | +end |
| 210 | + |
| 211 | + |
| 212 | +example : |
| 213 | + (fun (x : Nat × Nat) (y : Nat × Nat) => x.1 + y.2) |
| 214 | + = |
| 215 | + (fun (x : Nat × Nat) (z : Nat × Nat) => z.2 + x.1) := by |
| 216 | + funext (a, b) (c, d) |
| 217 | + show a + d = d + a |
| 218 | + rw [Nat.add_comm] |
| 219 | + |
| 220 | + |
| 221 | +namespace Hidden |
| 222 | + |
| 223 | +universe u |
| 224 | + |
| 225 | +theorem symm {α : Type u} {a b : α} (h : Eq a b) : Eq b a := |
| 226 | + match h with |
| 227 | + | rfl => rfl |
| 228 | + |
| 229 | +theorem trans {α : Type u} {a b c : α} (h₁ : Eq a b) (h₂ : Eq b c) : Eq a c := |
| 230 | + match h₁, h₂ with |
| 231 | + | rfl, rfl => rfl |
| 232 | + |
| 233 | +theorem congr {α β : Type u} {a b : α} (f : α → β) (h : Eq a b) : Eq (f a) (f b) := |
| 234 | + match h with |
| 235 | + | rfl => rfl |
| 236 | +end Hidden |
| 237 | + |
| 238 | + |
| 239 | +inductive Expr where |
| 240 | + | const : (n : Nat) → Expr |
| 241 | + | var : (n : Nat) → Expr |
| 242 | + | plus : (s : Expr) → (t : Expr) → Expr |
| 243 | + | times : (s : Expr) → (t : Expr) → Expr |
| 244 | +deriving Repr |
| 245 | + |
| 246 | +def Valuation := (Nat → Nat) |
| 247 | + |
| 248 | +def eval_expr (s : Expr) (ρ : Valuation) : Nat := |
| 249 | + match s with |
| 250 | + | Expr.const n => n |
| 251 | + | Expr.var n => ρ n |
| 252 | + | Expr.plus s t => (eval_expr s ρ) + (eval_expr t ρ) |
| 253 | + | Expr.times s t => (eval_expr s ρ) * (eval_expr t ρ) |
| 254 | + |
| 255 | +-- #eval eval_expr (Expr.plus (Expr.var 3) (Expr.times (Expr.const 2) (Expr.var 5))) (1+.) |
| 256 | + |
| 257 | +theorem eval_plus_comm (s t : Expr) (ρ : Valuation) : eval_expr (Expr.plus s t) ρ = eval_expr (Expr.plus t s) ρ := |
| 258 | + have lhs : eval_expr (Expr.plus s t) ρ = (eval_expr s ρ) + (eval_expr t ρ) := rfl |
| 259 | + have rhs : eval_expr (Expr.plus t s) ρ = (eval_expr t ρ) + (eval_expr s ρ) := rfl |
| 260 | + by rewrite [lhs, rhs]; apply Nat.add_comm |
| 261 | + |
| 262 | +def sampleVal : Nat → Nat |
| 263 | + | 0 => 5 |
| 264 | + | 1 => 6 |
| 265 | + | _ => 0 |
| 266 | + |
| 267 | +def sampleExpr : Expr := |
| 268 | + Expr.plus (Expr.times (Expr.var 0) (Expr.const 7)) (Expr.times (Expr.const 2) (Expr.var 1)) |
| 269 | + |
| 270 | +#eval eval_expr sampleExpr sampleVal |
| 271 | + |
| 272 | +open Expr |
| 273 | + |
| 274 | +def simpConst : Expr → Expr |
| 275 | + | plus (const n₁) (const n₂) => const (n₁ + n₂) |
| 276 | + | times (const n₁) (const n₂) => const (n₁ * n₂) |
| 277 | + | e => e |
| 278 | + |
| 279 | +def fuse : Expr → Expr |
| 280 | + | plus s t => simpConst ( plus (simpConst s) (simpConst t)) |
| 281 | + | times s t => simpConst ( times (simpConst s) (simpConst t)) |
| 282 | + | e => e |
| 283 | + |
| 284 | +#eval fuse (plus (const 2) (plus (const 2) (const 3))) |
| 285 | + |
| 286 | +theorem simpConst_eq (v : Valuation) |
| 287 | + : ∀ e : Expr, eval_expr (simpConst e) v = eval_expr e v := by |
| 288 | + intros e |
| 289 | + unfold simpConst |
| 290 | + split <;> repeat first | rfl | unfold eval_expr |
| 291 | + |
| 292 | +theorem fuse_eq (v : Nat → Nat) |
| 293 | + : ∀ e : Expr, eval_expr (fuse e) v = eval_expr e v := by |
| 294 | + intros e |
| 295 | + unfold fuse |
| 296 | + split <;> repeat first | rfl | rw [simpConst_eq] | rw [eval_expr] |
0 commit comments