阶乘N/(阶乘k*阶乘(N-k))是整数的Coq证明
我在Coq标准库中找不到证明阶乘N/(阶乘k*阶乘(N-k))是整数的Coq证明,coq,factorial,Coq,Factorial,我在Coq标准库中找不到证明N choose k是整数的证据。这个引理的一个简短的自包含的证明是什么 Lemma fact_divides N k: k <= N -> Nat.divide (fact k * fact (N - k)) (fact N). 引理fact_除以nk:k Nat.divide(fact k*fact(N-k))(fact N)。 我看到他们通过递归地定义choose,choose(N,k)=choose(N-1,k)+choose(N-1,k-1)
N choose k
是整数的证据。这个引理的一个简短的自包含的证明是什么
Lemma fact_divides N k: k <= N -> Nat.divide (fact k * fact (N - k)) (fact N).
引理fact_除以nk:k Nat.divide(fact k*fact(N-k))(fact N)。
我看到他们通过递归地定义choose
,choose(N,k)=choose(N-1,k)+choose(N-1,k-1)
避开了整个问题,然后显示choose(N,k)*k!*(N-k)!=N代码>
然而,如果不借助帕斯卡三角形也能直接证明上述内容,那就太好了。当我在堆栈上搜索它时,出现了许多“非正式”证明。*隐式地使用有理数的代数步骤,并且它们不需要费心证明它适用于严格的nat
除法
编辑:
多亏了@Bubbler下面的答案(基于),证明是正确的
简介。析构函数(fact_div_fact_fact k(N-k))为[d Hd]。
存在d。重写而不是笨拙的负号,我将声明如下:
Theorem fact_div_fact_fact : forall x y, exists e, fact (x + y) = e * (fact x * fact y).
我相信你可以从这个引理,结合(x+y)*fact2xy'
结束。
引理fact2_0:forall x,fact2 0 x=factx。
证明。
诱导x。
-自动的。
-简单。重写IHx。自动的。Qed。
引理fact2:对于所有xy,factx*fact2xy=fact(x+y)。
证明。
诱导x。
-介绍。简单。重写事实2_0。铃声。
-诱导y。
+简单。将(x+0)替换为x接环。铃声。
+简单。用环将(x+S y)替换为(S x+y)。重写是通过帕斯卡的三角真的不是“直接证明”?可除性被定义为将q p:=(存在w,p=q*w)
,在这种情况下,见证人w
正是choose(n,k)
。我希望得到一个不需要将表达式识别为某个递归方程的解的证明,这通常需要一些神圣的洞察力,而是为了一个只涉及代数运算的简单证明。必须引入素数、代数基本定理等概念,或者在这种情况下,提出choose
,等等,这感觉有点过分了(尽管很漂亮)。非正式的证明只要求k个连续整数的乘积总是可以被k整除!,(除了“作弊”的合理划分……)这听起来很公平。我认为证明的所有困难都可以在你提到的最后一个事实中找到,因为,根据你如何形式化它,它的陈述几乎可以成为你试图证明的目标。是的,这是真的。这不是一个Coq问题,而是一个简单的数学问题。谢谢,这太完美了!
From Coq Require Import Arith.
(* Let's prove that (n+m)! is divisible by n! * m!. *)
(* fact2 x y = (x+1) * (x+2) * .. * (x+y) *)
Fixpoint fact2 x y := match y with
| O => 1
| S y' => (x + y) * fact2 x y'
end.
Lemma fact2_0 : forall x, fact2 0 x = fact x.
Proof.
induction x.
- auto.
- simpl. rewrite IHx. auto. Qed.
Lemma fact_fact2 : forall x y, fact x * fact2 x y = fact (x + y).
Proof.
induction x.
- intros. simpl. rewrite fact2_0. ring.
- induction y.
+ simpl. replace (x + 0) with x by ring. ring.
+ simpl. replace (x + S y) with (S x + y) by ring. rewrite <- IHy. simpl. ring. Qed.
Lemma fact2_left : forall x y, fact2 x (S y) = S x * fact2 (S x) y.
Proof. intros x y. generalize dependent x. induction y.
- intros. simpl. ring.
- intros. unfold fact2. fold (fact2 x (S y)). fold (fact2 (S x) y).
rewrite IHy. ring. Qed.
Lemma fact_div_fact2 : forall x y, exists e, fact2 x y = e * fact y.
Proof. intros x y. generalize dependent x. induction y.
- intros. simpl. exists 1. auto.
- induction x.
+ unfold fact2. fold (fact2 0 y). unfold fact. fold (fact y). destruct (IHy 0). rewrite H.
exists x. ring.
+ unfold fact2. fold (fact2 (S x) y).
destruct (IHy (S x)). destruct IHx. exists (x0 + x1).
replace ((S x + S y) * fact2 (S x) y) with (S x * fact2 (S x) y + S y * fact2 (S x) y) by ring.
rewrite <- fact2_left. rewrite H0. rewrite H.
replace (S y * (x0 * fact y)) with (x0 * (S y * fact y)) by ring.
unfold fact. fold (fact y). ring. Qed.
Theorem fact_div_fact_fact : forall x y, exists e, fact (x + y) = e * (fact x * fact y).
Proof. intros x y. destruct (fact_div_fact2 x y). exists x0.
rewrite <- fact_fact2. rewrite H. ring. Qed.