Lean , 66 byte
def s:_->nat->nat|(m+1)(n+1):=(n+1)*(s m n+s m(n+1))|0 0:=1|_ _:=0
Hãy thử trực tuyến!
Bằng chứng chính xác
Hãy thử trực tuyến!
Giải trình
Hãy để chúng tôi ungolf chức năng:
def s : nat->nat->nat
| (m+1) (n+1) := (n+1)*(s m n + s m (n+1))
| 0 0 := 1
| _ _ := 0
Hàm được xác định bởi khớp mẫu và đệ quy, cả hai đều có hỗ trợ tích hợp.
Chúng tôi xác định s(m+1, n+1) = (n+1) * (s(m, n) + s(m, n+1)
và s(0, 0) = 1
, để lại mở s(m+1, 0)
và s(0, n+1)
, cả hai đều được xác định là 0
trường hợp cuối cùng.
Nạc sử dụng cú pháp lamdba calculus, vì vậy s m n
là s(m, n)
.
Bây giờ, bằng chứng về sự đúng đắn: tôi đã nêu nó theo hai cách:
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
Điều đầu tiên là những gì đang thực sự diễn ra: một sự lựa chọn giữa [0 ... s(m, n)-1]
và sự từ bỏ từ [0 ... m-1]
trên xuống [0 ... n-1]
.
Cái thứ hai là cách nó thường được nêu, đó s(m, n)
là tính chính xác của các từ đầu [0 ... m-1]
ra [0 ... n-1]
.
Lean sử dụng lý thuyết loại làm nền tảng của nó (thay vì lý thuyết tập hợp). Trong lý thuyết loại, mọi đối tượng đều có một loại vốn có của nó. nat
là loại số tự nhiên và câu lệnh 0
là số tự nhiên được biểu thị là 0 : nat
. Chúng ta nói rằng 0
là loại nat
, và đó nat
có 0
là một cư dân.
Các đề xuất (tuyên bố / khẳng định) cũng là loại: cư dân của họ là một bằng chứng của các đề xuất.
def
: Chúng tôi sẽ giới thiệu một định nghĩa (bởi vì một bijection thực sự là một chức năng, không chỉ là một đề xuất).
correctness
: tên của định nghĩa
∀ m n
: cho mọi m
và n
(Lean tự động cho rằng loại của chúng là nat
vì những gì tiếp theo).
fin (s m n)
là loại số tự nhiên nhỏ hơn s m n
. Để làm cho một cư dân, người ta cung cấp một số tự nhiên và một bằng chứng rằng nó nhỏ hơn s m n
.
A ≃ B
: bijection giữa loại A
và loại B
. Nói bijection là sai lệch, vì người ta thực sự phải cung cấp chức năng nghịch đảo.
{ f : fin m → fin n // function.surjective f }
các loại từ trên fin m
đến fin n
. Cú pháp này xây dựng một kiểu con từ loại fin m → fin n
, tức là loại hàm từ fin m
đến fin n
. Cú pháp là { var : base type // proposition about var }
.
λ m
: ∀ var, proposition / type involving var
thực sự là một hàm lấy var
đầu vào, vì vậy λ m
giới thiệu đầu vào. ∀ m n,
là tay ngắn cho∀ m, ∀ n,
nat.rec_on m
: làm đệ quy trên m
. Để xác định một cái gì đó cho m
, xác định điều cho 0
và sau đó đưa ra điều cho k
, xây dựng điều cho k+1
. Người ta sẽ nhận thấy rằng điều này tương tự như cảm ứng, và thực sự đây là kết quả của sự tương ứng của Church-Howard . Cú pháp là 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, điều này đang trở nên dài và tôi chỉ ở dòng thứ ba của correctness
...