software_foundation/basics/main.lean

353 lines
6.1 KiB
Text
Raw Normal View History

2024-09-25 21:21:34 +09:00
--- Data and Functions
inductive Day : Type :=
| Monday
| Tuesday
| Wednesday
| Thursday
| Friday
| Saturday
| Sunday
deriving Repr
def next_weekday (d : Day) : Day :=
match d with
| .Monday => .Tuesday
| .Tuesday => .Wednesday
| .Wednesday => .Thursday
| .Thursday => .Friday
| .Friday | .Saturday | .Sunday => .Monday
#eval next_weekday Day.Friday
#eval next_weekday (next_weekday .Saturday)
theorem test_next_weekday : next_weekday (next_weekday .Saturday) = .Tuesday := by
rfl
--- Booleans
#print bool
#eval not true
#print not
#print and
#print or
example : or true false = true := by rfl
example : or false false = false := by rfl
example : or false true = true := by rfl
example : or true true = true := by rfl
#eval true false
example : true false = true := by
simp
example : false false true = true := by
simp
def negb' (b : Bool) : Bool :=
if b then false
else true
#eval negb' true
example : negb' true = ¬ true := by
simp
rfl
--- Exercise 1
namespace Exercise1
def nandb (b₁ : Bool) (b₂ : Bool) : Bool :=
match (b₁, b₂) with
| (true, true) => false
| _ => true
example : (nandb true false) = true := by
rfl
example : (nandb false false) = true := by
rfl
example : (nandb false true) = true := by
rfl
example : (nandb true true) = false := by
rfl
def andb3
| true, true, true => true
| _, _, _ => false
example : andb3 true true true = true := by rfl
example : andb3 false true true = false := by rfl
example : andb3 true false true = false := by rfl
example : andb3 true true false = false := by rfl
end Exercise1
--- Types
#check true
#check Bool.not
#check true.not
#check not
--- New Types from Old
inductive Rgb : Type :=
| red
| green
| blue
inductive Color : Type :=
| black
| white
| primary (p : Rgb)
#check Color.primary
def monochrome (c : Color) : Bool :=
match c with
| .black => true
| .white => true
| .primary _p => false
def isred (c : Color) : Bool :=
match c with
| .primary .red => true
| _ => false
--- Modules
namespace Playground
def foo : Rgb := .blue
end Playground
def foo : Bool := true
#check Playground.foo
#check foo
--- Tuples
namespace TuplePlayground
inductive Bit : Type :=
| B₁
| B₀
inductive Nybble :=
| bits (b₀ b₁ b₂ b₃ : Bit)
#print Nybble
#check Nybble.bits .B₁ .B₀ .B₁ .B₀
def all_zero (nb : Nybble) : Bool :=
match nb with
| .bits .B₀ .B₀ .B₀ .B₀ => true
| .bits _ _ _ _ => false
#eval all_zero (.bits .B₁ .B₁ .B₁ .B₁)
#eval all_zero (.bits .B₀ .B₀ .B₀ .B₀)
end TuplePlayground
--- Numbers
namespace NatPlayground
2024-09-26 04:36:06 +09:00
#eval Nat.zero
#eval Nat.zero.succ
#eval Nat.zero.succ.succ
example : Nat.zero.succ.succ = 2 := by rfl
2024-09-25 21:21:34 +09:00
end NatPlayground
2024-09-26 04:36:06 +09:00
open Nat in
#check succ (succ (succ 0))
def minustwo (n : Nat) : Nat :=
match n with
| 0 => 0
| .succ .zero => 0
| .succ (.succ n') => n'
#eval minustwo 4
def even (n : Nat) : Bool :=
match n with
| .zero => true
| .succ .zero => false
| .succ (.succ n') => even n'
example : even 4 = true := by
rfl
example : even 51 = false := by
rfl
namespace NatPlayground2
def plus (n : Nat) (m : Nat) : Nat :=
match n with
| .zero => m
| .succ n' => .succ (plus n' m)
#eval plus 3 4
def mult (n m : Nat) : Nat :=
match n with
| .zero => .zero
| .succ n' => plus m (mult n' m)
end NatPlayground2
namespace Exercise1
def factorial (n : Nat) : Nat :=
match n with
| 0 => 1
| .succ n' => (n' + 1) * factorial n'
#eval factorial 3
example : factorial 3 = 6 := by
rfl
example : factorial 5 = .mul 10 12 := by
rfl
end Exercise1
#check LT.lt 1 2
#check LT Nat
#check (LT Nat)
#check Nat.lt 1 2
namespace Exercise1
def ltb (n m : Nat) : Bool :=
match n, m with
| 0, _ => true
| _, 0 => false
| .succ n', .succ m' => ltb n' m'
#eval ltb 1 2
#eval ltb 10242 1055090
example : (ltb 1 2) = true := by rfl
end Exercise1
--- Proof by Simplification
2025-01-08 01:27:21 +09:00
theorem plus_0_n : ∀ n : Nat, 0 + n = n := by
intros n
simp
#check ∀ n : Nat, 0 + n = n
example : ∀ n : Nat, 1 + n = .succ n := by
intros m
simp
apply Nat.add_comm 1 m
example : ∀ n : Nat, 0 * n = 0 := by
intros n
exact Nat.zero_mul n
--- Proof by Rewriting
example : ∀ n m : Nat, n = m → n + n = m + m := by
intros n m h
rw [h]
namespace Exercise1
theorem plus_id_exercise : ∀ n m o : Nat, n = m → m = o → n + m = m + o := by
intros n m o h₁ h₂
rw [h₁]
rw [h₂]
#check plus_0_n
theorem mult_n_1 : ∀ p : Nat, p * 1 = p := by
intros p
cases p
. rw [Nat.mul_one]
. rw [Nat.mul_one]
example : ∀ p : Nat, p * 1 = p := by
intros p
rw [Nat.mul_one]
#check Nat.mul_zero
#check Nat.mul_succ
example : ∀ p : Nat, p * 1 = p := by
intros
rw [Nat.mul_succ]
rw [Nat.mul_zero]
simp
end Exercise1
#eval (1).succ.succ.succ
#eval [1, 2, 3, 4].foldl (· + ·) 0
#print Array.foldl
#print optParam
--- Proof by Case Analysis
example : ∀ n : Nat, ((n + 1) = 0) = False := by
intros n
cases n
case zero => simp only [Nat.zero_add, Nat.add_one_ne_zero]
case succ => simp only [Nat.add_one_ne_zero]
example : ∀ b : Bool, ¬ (¬ b) = b := by
intros b
cases b
. simp
. rw [Lean.Grind.not_eq_prop]
example : ∀ b c : Bool, (b ∧ c) = (c ∧ b) := by
intros b c
cases b
. cases c
. simp only [Bool.false_eq_true, and_self]
. rw [@and_comm]
. rw [@and_comm]
#eval true ∧ true
#eval (true ∧ true) = (true ∧ true)
#eval true ∧ false = false ∧ true
#eval false ∧ false = false ∧ false
#eval (false ∧ false) = (false ∧ false)
#eval Bool.and true true
#eval Bool.true ∧ Bool.true
#eval true && false = false && true
#print and_comm
namespace Exercise
example : ∀ b c : Bool, (Bool.and b c = true) → (c = true) := by
intros b c
cases c
case true => exact fun _a => rfl
case false =>
cases b
case true =>
intros h
exact h
case false =>
intros h
exact h
#print id
#check Function.const
example : ∀ n : Nat, (0 == (n + 1)) = false := by
intros n
cases n
. simp only [Nat.zero_add, Nat.reduceBEq]
. simp only [Nat.reduceBeqDiff]
end Exercise
--- More on Notation
-- skipping
--- More Exercises