用Coq编写简单算法的证明

用Coq编写简单算法的证明,coq,integer-arithmetic,Coq,Integer Arithmetic,我想证明简单的事情,比如对于每个自然数n,存在一个自然数k,这样: (2*n + 1)^2 = 8*k + 1 如何进行这样的证明?当n是奇数或偶数时,我想把它分成几类,但我不知道如何在Coq中这样做。此外,Coq中是否有内置的幂(指数)运算符?是的,有许多内置函数,您只需要正确的导入集或打开正确的表示范围。 做证明的一个简单方法是使用归纳法和一些自动化方法,如,或战术 我们可以按照案例推理问题中建议的初始方案,即输入是奇数还是偶数,仅通过n mod 2的值表示奇偶性,并使用布尔等式测试来表示

我想证明简单的事情,比如对于每个自然数n,存在一个自然数k,这样:

(2*n + 1)^2 = 8*k + 1

如何进行这样的证明?当n是奇数或偶数时,我想把它分成几类,但我不知道如何在Coq中这样做。此外,Coq中是否有内置的幂(指数)运算符?

是的,有许多内置函数,您只需要正确的导入集或打开正确的表示范围。 做证明的一个简单方法是使用归纳法和一些自动化方法,如,或战术


我们可以按照案例推理问题中建议的初始方案,即输入是奇数还是偶数,仅通过
n mod 2
的值表示奇偶性,并使用布尔等式测试来表示备选方案

也可以用相对整数而不是自然数来证明

From Coq Require Import ZArith Psatz.

Open Scope Z_scope.

Lemma example n : exists k,  (2 * n + 1) ^2 = 8 * k + 1.
Proof.
assert (vn : n = 2 * (n / 2) + n mod 2) by now apply Z_div_mod_eq.
destruct (n mod 2 =? 0) eqn: q.
-  rewrite Z.eqb_eq in q; rewrite vn, q.
exists ((2 * (n / 2) + 1) * (n / 2)); ring.
-  enough (vm : n mod 2 = 1)
    by now rewrite vn, vm; exists (2 * (n / 2) ^ 2 + 3 * (n / 2) + 1); ring.
rewrite Z.eqb_neq in q.
assert (0 <= n mod 2 < 2) by now apply Z_mod_lt.
lia.
Qed.
从Coq需要导入ZArith Psatz。
打开范围Z_范围。
引理示例n:存在k,(2*n+1)^2=8*k+1。
证明。
断言(vn:n=2*(n/2)+n mod 2)现在应用Z_div_mod_eq。
自毁(n mod 2=?0)等式n:q。
-重写q中的Z.eqb_eq;重写vn,q。
存在((2*(n/2)+1)*(n/2));铃声。
-足够(vm:n mod 2=1)
现在重写vn,vm;存在(2*(n/2)^2+3*(n/2)+1);铃声。
在q中重写Z.eqb_neq。

断言(0这里是一个替代证明,使用了@Yves在证明中发现的相同思想:

From Coq Require Import Arith Psatz.

Fact exampleNat n : exists k, (2 * n + 1) ^2 = 8 * k + 1.
Proof.
  exists (n * (S n) / 2).
  assert (H : Nat.even (n * (S n)) = true) by
    now rewrite Nat.even_mul, Nat.even_succ, Nat.orb_even_odd.
  apply Nat.even_spec in H as [m H]; rewrite (Nat.mul_comm 2) in H.
  rewrite H, Nat.div_mul, Nat.pow_2_r; lia.
Qed.
请注意,如果您将名称空间
Nat
更改为
Z
S
更改为
Z.succ
),则此验证模式也适用于整数

From Coq Require Import Arith Psatz.

Fact exampleNat n : exists k, (2 * n + 1) ^2 = 8 * k + 1.
Proof.
  exists (n * (S n) / 2).
  assert (H : Nat.even (n * (S n)) = true) by
    now rewrite Nat.even_mul, Nat.even_succ, Nat.orb_even_odd.
  apply Nat.even_spec in H as [m H]; rewrite (Nat.mul_comm 2) in H.
  rewrite H, Nat.div_mul, Nat.pow_2_r; lia.
Qed.