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 0
oleh kasus terakhir.
Lean menggunakan sintaks kalkulus lamdba, begitu s m n
juga 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. nat
adalah jenis bilangan asli, dan pernyataan yang 0
merupakan bilangan alami dinyatakan sebagai 0 : nat
. Kami mengatakan bahwa itu 0
adalah tipe nat
, dan yang nat
memiliki 0
sebagai 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 m
dan 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 A
dan jenisnya B
. Mengatakan bijection menyesatkan, karena seseorang harus menyediakan fungsi terbalik.
{ f : fin m → fin n // function.surjective f }
jenis surjections dari fin m
ke fin n
. Sintaks ini membangun subtipe dari tipe fin m → fin n
, yaitu tipe fungsi dari fin m
hingga fin n
. Sintaksnya adalah { var : base type // proposition about var }
.
λ m
: ∀ var, proposition / type involving var
benar-benar fungsi yang dibutuhkan var
sebagai input, jadi λ m
perkenalkan input. ∀ m n,
adalah kependekan dari∀ m, ∀ n,
nat.rec_on m
: lakukan rekursi pada m
. Untuk menentukan sesuatu untuk m
, menentukan hal untuk 0
dan 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
...