Lean , 66 byte
def s:_->nat->nat|(m+1)(n+1):=(n+1)*(s m n+s m(n+1))|0 0:=1|_ _:=0
Cobalah online!
Bukti kebenaran
Cobalah online!
Penjelasan
Mari kita ungolf fungsinya:
def s : nat->nat->nat
| (m+1) (n+1) := (n+1)*(s m n + s m (n+1))
| 0 0 := 1
| _ _ := 0
Fungsi ini ditentukan oleh pencocokan pola dan rekursi, yang keduanya memiliki dukungan bawaan.
Kami mendefinisikan s(m+1, n+1) = (n+1) * (s(m, n) + s(m, n+1)dan s(0, 0) = 1, yang meninggalkan terbuka s(m+1, 0)dan s(0, n+1), keduanya didefinisikan 0oleh kasus terakhir.
Lean menggunakan sintaks kalkulus lamdba, begitu s m njuga s(m, n).
Sekarang, bukti kebenaran: Saya menyatakannya dalam dua cara:
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
Yang pertama adalah apa yang sebenarnya terjadi: bijection antara [0 ... s(m, n)-1]dan surjections dari [0 ... m-1]ke [0 ... n-1].
Yang kedua adalah bagaimana biasanya dinyatakan, bahwa s(m, n)adalah kardinalitas dari surjections dari [0 ... m-1]ke [0 ... n-1].
Lean menggunakan teori tipe sebagai fondasinya (bukan teori himpunan). Dalam teori tipe, setiap objek memiliki tipe yang melekat padanya. natadalah jenis bilangan asli, dan pernyataan yang 0merupakan bilangan alami dinyatakan sebagai 0 : nat. Kami mengatakan bahwa itu 0adalah tipe nat, dan yang natmemiliki 0sebagai penduduk.
Proposisi (pernyataan / pernyataan) juga tipe: penghuninya adalah bukti proposisi.
def: Kami akan memperkenalkan definisi (karena bijection benar-benar fungsi, bukan hanya proposisi).
correctness: nama definisi
∀ m n: untuk setiap mdan n(Lean secara otomatis menyimpulkan bahwa tipenya adalah nat, karena apa yang berikut).
fin (s m n)adalah jenis bilangan alami yang lebih kecil dari s m n. Untuk membuat penghuni, orang memberikan nomor alami dan bukti bahwa itu lebih kecil dari s m n.
A ≃ B: bijection antara jenis Adan jenisnya B. Mengatakan bijection menyesatkan, karena seseorang harus menyediakan fungsi terbalik.
{ f : fin m → fin n // function.surjective f }jenis surjections dari fin mke fin n. Sintaks ini membangun subtipe dari tipe fin m → fin n, yaitu tipe fungsi dari fin mhingga fin n. Sintaksnya adalah { var : base type // proposition about var }.
λ m: ∀ var, proposition / type involving varbenar-benar fungsi yang dibutuhkan varsebagai input, jadi λ mperkenalkan input. ∀ m n,adalah kependekan dari∀ m, ∀ n,
nat.rec_on m: lakukan rekursi pada m. Untuk menentukan sesuatu untuk m, menentukan hal untuk 0dan kemudian memberikan hal untuk k, membangun hal untuk k+1. Orang akan melihat bahwa ini mirip dengan induksi, dan memang ini adalah hasil dari korespondensi Gereja-Howard . Sintaksnya adalah 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").
Heh, ini semakin lama dan aku hanya di baris ketiga correctness...