Functional programming Coq:证明n和(sn)的乘积是偶数
给定过程Functional programming Coq:证明n和(sn)的乘积是偶数,functional-programming,coq,Functional Programming,Coq,给定过程even,我想证明所有自然数n的even(n*(sn))=true 使用归纳法,对于n=0的情况,这很容易被视为true。然而,这种情况很难简化 我考虑过证明引理偶数(m*n)=偶数m/\偶数n,但这似乎并不容易 此外,很容易看出如果偶数n=trueiff偶数(SN)=假 Fixpoint even (n: nat) : bool := match n with | O => true | 1 => false | S (S n') => even n'
even
,我想证明所有自然数n
的even(n*(sn))=true
使用归纳法,对于n=0
的情况,这很容易被视为true
。然而,这种情况很难简化
我考虑过证明引理偶数(m*n)=偶数m/\偶数n
,但这似乎并不容易
此外,很容易看出如果偶数n=true
iff<代码>偶数(SN)=假
Fixpoint even (n: nat) : bool :=
match n with
| O => true
| 1 => false
| S (S n') => even n'
end.
有人能给出一个如何用Coq的“初学者”子集证明这一点的提示吗?在这种情况下,更高级的归纳法原理是有用的。在中对其进行了简要描述 现在,让我们定义几个辅助引理。它们是显而易见的,并且可以很容易地用
成对感应法原理和一些自动证明来证明
Lemma even_mul2 : forall n, Nat.even (2 * n) = true.
Proof.
induction n; auto.
now replace (2 * S n) with (2 + 2 * n) by ring.
Qed.
Lemma even_add_even : forall m n,
Nat.even m = true ->
Nat.even (m + n) = Nat.even n.
Proof.
now induction m using pair_induction; auto.
Qed.
Lemma even_add_mul2 : forall m n,
Nat.even (2 * m + n) = Nat.even n.
Proof.
intros; apply even_add_even, even_mul2.
Qed.
Lemma even_S : forall n,
Nat.even (S n) = negb (Nat.even n).
Proof.
induction n; auto.
simpl (Nat.even (S (S n))). (* not necessary -- just to make things clear *)
apply negb_sym. assumption.
Qed.
下面的引理说明了如何在乘法上“分配”偶数。它在证明我们的主要目标方面起着重要作用。几乎总是这样,泛化帮助很大
Lemma even_mult : forall m n,
Nat.even (m * n) = Nat.even m || Nat.even n.
Proof.
induction m using pair_induction; simpl; auto.
intros n. replace (n + (n + m * n)) with (2 * n + m * n) by ring.
now rewrite even_add_mul2.
Qed.
现在,目标的证明是微不足道的
Goal forall n, Nat.even (n * (S n)) = true.
intros n. now rewrite even_mult, even_S, orb_negb_r.
Qed.
有人能给出一个提示,说明如何使用Coq的“初学者”子集来证明这一点吗
你可以考虑这个暗示,因为它揭示了一个可能的证据的一般结构。自动策略可能会被“手动”策略所取代,如
重写
,应用
,销毁
等等。我想用mathcomp库提供一个简短的证明:
From mathcomp Require Import all_ssreflect all_algebra.
Lemma P n : ~~ odd (n * n.+1).
Proof. by rewrite odd_mul andbN. Qed.
odd_mul
是通过简单归纳法证明的,以及另一个版本的odd_add
也是根据@ejgallego的回答精神证明的。
让我们为偶数谓词给出另一个定义。这样做的目的是使通过简单归纳法进行证明变得容易,因此不需要使用成对归纳法
。主要思想是,我们要证明even2
的一些性质,然后我们将使用Nat.even
和even2
在广义上等同于将even2
的性质转移到Nat.even
上
Require Import Coq.Bool.Bool.
Fixpoint even2 (n : nat) : bool :=
match n with
| O => true
| S n' => negb (even2 n')
end.
让我们证明Nat.even
和even2
在扩展上是相等的
Lemma even_S n :
Nat.even (S n) = negb (Nat.even n).
Proof. induction n; auto. apply negb_sym; assumption. Qed.
Lemma even_equiv_even2 n :
Nat.even n = even2 n.
Proof. induction n; auto. now rewrite even_S, IHn. Qed.
even2
的一些分布引理:
Lemma even2_distr_add m n :
even2 (m + n) = negb (xorb (even2 m) (even2 n)).
Proof.
induction m; simpl.
- now destruct (even2 n).
- rewrite IHm. now destruct (even2 m); destruct (even2 n).
Qed.
Lemma even2_distr_mult m n :
even2 (m * n) = even2 m || even2 n.
Proof.
induction m; auto; simpl.
rewrite even2_distr_add, IHm.
now destruct (even2 m); destruct (even2 n).
Qed.
最后,我们能够证明我们的目标,使用Nat.even
和even2
之间的等式
Goal forall n, Nat.even (n * (S n)) = true.
intros n.
now rewrite even_equiv_even2, even2_distr_mult, orb_negb_r.
Qed.
使用标准库的简短版本:
Require Import Coq.Arith.Arith.
Goal forall n, Nat.even (n * (S n)) = true.
intros n.
now rewrite Nat.even_mul, Nat.even_succ, Nat.orb_even_odd.
Qed.
值得一提的是,以下是我对解决方案的看法。基本思想是,不是证明谓词pn
,而是证明pn/\P(sn)
,这是等价的,但第二个公式允许使用简单归纳法
以下是完整的证据:
Require Import Nat.
Require Import Omega.
Definition claim n := even (n * (S n)) = true.
(* A technical Lemma, needed in the proof *)
Lemma tech: forall n m, even n = true -> even (n + 2*m) = true.
Proof.
intros. induction m.
* simpl. replace (n+0) with n; intuition.
* replace (n + 2 * S m) with (S (S (n+2*m))); intuition.
Qed.
(* A simple identity, that Coq needs help to prove *)
Lemma ident: forall n,
(S (S n) * S (S (S n))) = (S n * S( S n) + 2*(S (S n))).
(* (n+2)*(n+3) = (n+1)*(n+2) + 2*(n+2) *)
Proof.
intro.
replace (S (S (S n))) with ((S n) + 2) by intuition.
remember (S (S n)) as m.
replace (m * (S n + 2)) with ((S n + 2) * m) by intuition.
intuition.
Qed.
(* The claim to be proved by simple induction *)
Lemma nsn: forall n, claim n /\ claim (S n).
Proof.
intros.
unfold claim.
induction n.
* intuition.
* intuition. rewrite ident. apply tech; auto.
Qed.
(* The final result is now a simple corollary *)
Theorem thm: forall n, claim n.
Proof.
apply nsn.
Qed.
我将开始证明偶数n->偶数(n*m)
(对于所有m
)。既然偶数n(偶数(sn)=false)
和n*m=m*n
你应该能够证明偶数(n*(sn))
。不确定这是否简化了任何事情……你认为“偶数n->偶数(n*m)”很容易证明吗?也许。考虑:<代码> n*(s m′)=n+n*m′/代码>由归纳假设<代码> n*m′/代码>是偶数和<代码>甚至n/\m-甚至(n+m)这都会产生论文。谢谢,但是“偶数(n+m)”似乎很难证明(虽然一见钟情)。为什么?如果n=O
,那么使用siml
可以得到n+m=m
,这在假设中是偶数。如果n=(S(sn'))
然后使用siml
得到S(n'+m))
,通过归纳假设+事实偶数n偶数(S(sn))
得出论文。您只需要偶数n->(n=O\/n=S(sn')/\偶数n')
这似乎不难归纳证明。证明中的orb是什么?真的需要成对归纳吗?(1)您可以发出以下查询:打印orb。
检查它是什么。它是布尔“或”。当然,你可以不用结对归纳法,记住,它是用户定义的,不是隐藏的Coq机制。这只是一种强化归纳假设的方法。@Shuzheng我简化了目标的证明。如果将偶数定义为不动点偶数(n:nat):bool:=将n与| O=>true | sn'=>negb(偶数n')端匹配,则证明可能会更简单。
这里的奇数
的定义与问题中的偶数
的结构不同,这就是为什么简单归纳法在这种情况下效果很好。我很难证明“偶数加偶数”。我在问题中附上了我的部分证据。这里的“nat_ind2”是您的“结对感应”。你能告诉我如何继续吗?siml。重写IH_m'。自反性。H中的simple。应用H。
谢谢,这是一个很好的证明:-)
Require Import Nat.
Require Import Omega.
Definition claim n := even (n * (S n)) = true.
(* A technical Lemma, needed in the proof *)
Lemma tech: forall n m, even n = true -> even (n + 2*m) = true.
Proof.
intros. induction m.
* simpl. replace (n+0) with n; intuition.
* replace (n + 2 * S m) with (S (S (n+2*m))); intuition.
Qed.
(* A simple identity, that Coq needs help to prove *)
Lemma ident: forall n,
(S (S n) * S (S (S n))) = (S n * S( S n) + 2*(S (S n))).
(* (n+2)*(n+3) = (n+1)*(n+2) + 2*(n+2) *)
Proof.
intro.
replace (S (S (S n))) with ((S n) + 2) by intuition.
remember (S (S n)) as m.
replace (m * (S n + 2)) with ((S n + 2) * m) by intuition.
intuition.
Qed.
(* The claim to be proved by simple induction *)
Lemma nsn: forall n, claim n /\ claim (S n).
Proof.
intros.
unfold claim.
induction n.
* intuition.
* intuition. rewrite ident. apply tech; auto.
Qed.
(* The final result is now a simple corollary *)
Theorem thm: forall n, claim n.
Proof.
apply nsn.
Qed.