ลีน , 66 ไบต์
def s:_->nat->nat|(m+1)(n+1):=(n+1)*(s m n+s m(n+1))|0 0:=1|_ _:=0
ลองออนไลน์!
พิสูจน์ความถูกต้อง
ลองออนไลน์!
คำอธิบาย
ให้เราปลดเปลื้องฟังก์ชั่น:
def s : nat->nat->nat
| (m+1) (n+1) := (n+1)*(s m n + s m (n+1))
| 0 0 := 1
| _ _ := 0
ฟังก์ชันถูกกำหนดโดยการจับคู่รูปแบบและการเรียกซ้ำซึ่งทั้งสองอย่างมีการสนับสนุนในตัว
เรากำหนดs(m+1, n+1) = (n+1) * (s(m, n) + s(m, n+1)
และs(0, 0) = 1
ซึ่งเปิดทิ้งไว้s(m+1, 0)
และs(0, n+1)
ทั้งสองอย่างถูกกำหนดให้เป็น0
กรณีสุดท้าย
การใช้งานแบบ Lean ไวยากรณ์ lamdba แคลคูลัสเพื่อให้เป็นs m n
s(m, n)
ตอนนี้พิสูจน์ความถูกต้อง: ฉันระบุไว้ในสองวิธี:
def correctness : ∀ m n, fin (s m n) ≃ { f : fin m → fin n // function.surjective f } :=
λ m, nat.rec_on m (λ n, nat.cases_on n s_zero_zero (λ n, s_zero_succ n)) $
λ m ih n, nat.cases_on n (s_succ_zero m) $ λ n,
calc fin (s (nat.succ m) (nat.succ n))
≃ (fin (n + 1) × (fin (s m n + s m (n + 1)))) :
(fin_prod _ _).symm
... ≃ (fin (n + 1) × (fin (s m n) ⊕ fin (s m (n + 1)))) :
equiv.prod_congr (equiv.refl _) (fin_sum _ _).symm
... ≃ (fin (n + 1) × ({f : fin m → fin n // function.surjective f} ⊕
{f : fin m → fin (n + 1) // function.surjective f})) :
equiv.prod_congr (equiv.refl _) (equiv.sum_congr (ih n) (ih (n + 1)))
... ≃ {f // function.surjective f} : s_aux m n
def correctness_2 (m n : nat) : s m n = fintype.card { f : fin m → fin n // function.surjective f } :=
by rw fintype.of_equiv_card (correctness m n); simp
คนแรกคือสิ่งที่เป็นจริงที่เกิดขึ้น: bijection ระหว่าง[0 ... s(m, n)-1]
และ surjections จากบน[0 ... m-1]
[0 ... n-1]
อย่างที่สองคือวิธีที่กล่าวไว้โดยทั่วไปนั่นs(m, n)
คือความสำคัญของการสะท้อนจาก[0 ... m-1]
บนลง[0 ... n-1]
ล่าง
Lean ใช้ทฤษฎีชนิดเป็นรากฐาน (แทนที่จะเป็นทฤษฎีเซต) ในทฤษฎีประเภทวัตถุทุกชนิดมีชนิดที่มีอยู่ nat
เป็นประเภทของจำนวนธรรมชาติและคำว่าเป็นจำนวนธรรมชาติจะแสดงเป็น0
0 : nat
เราพูด0
แบบnat
นั้นและนั่นnat
ก็0
เป็นแบบผู้อยู่อาศัย
ข้อเสนอ (ข้อความ / ยืนยัน) ก็เป็นประเภท: ผู้อยู่อาศัยของพวกเขาเป็นข้อพิสูจน์ของข้อเสนอ
def
: เราจะนำคำจำกัดความมาใช้ (เพราะการให้ความเห็นทางชีวภาพนั้นเป็นฟังก์ชั่นจริงๆ
correctness
: ชื่อของคำจำกัดความ
∀ m n
: สำหรับทุก ๆm
และn
(แบบลีนโดยอัตโนมัติจะระบุว่าประเภทของพวกเขาคือnat
เพราะสิ่งต่อไปนี้)
fin (s m n)
s m n
เป็นประเภทของจำนวนธรรมชาติที่มีขนาดเล็กกว่า s m n
ที่จะทำให้ชาวเมืองหนึ่งมีจำนวนธรรมชาติและพิสูจน์ให้เห็นว่ามันมีขนาดเล็กกว่า
A ≃ B
: bijection ระหว่างประเภทและชนิดA
B
การบอกว่า bijection นั้นทำให้เข้าใจผิดเป็นจริงอย่างใดอย่างหนึ่งมีให้ฟังก์ชันผกผัน
{ f : fin m → fin n // function.surjective f }
ประเภทของ surjections จากไปfin m
fin n
ไวยากรณ์นี้สร้างจากชนิดย่อยได้fin m → fin n
เช่นประเภทของฟังก์ชั่นจากไปfin m
ไวยากรณ์fin n
{ var : base type // proposition about var }
λ m
: ∀ var, proposition / type involving var
เป็นฟังก์ชันที่ใช้var
เป็นอินพุตดังนั้นλ m
แนะนำอินพุต ∀ m n,
มือสั้นสำหรับ∀ m, ∀ n,
nat.rec_on m
: ทำ recursion m
บน ในการกำหนดสิ่งที่ต้องการm
ให้กำหนดสิ่งที่ต้องการ0
และจากนั้นให้สิ่งk
นั้นสร้างสิ่งที่k+1
ต้องการ หนึ่งจะสังเกตเห็นว่านี้จะคล้ายกับการเหนี่ยวนำและแน่นอนนี้เป็นผลมาจากคริสตจักรโฮเวิร์ดจดหมาย nat.rec_on var (thing when var is 0) (for all k, given "thing when k is k", build thing when var is "k+1")
ไวยากรณ์
เฮ้นี่มันนานมากแล้วและฉันก็อยู่ในบรรทัดที่สามของcorrectness
...