阶乘N/(阶乘k*阶乘(N-k))是整数的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)

我在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)
避开了整个问题,然后显示
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.