在Coq

时间:2017-02-20 10:24:48

标签: coq theorem-proving

在数学方面,我们经常按如下方式进行:"现在让我们考虑两种情况,k可以是evenodd。对于even案例,我们可以说exists k', 2k' = k ..."

通过将其分解为几个可用于重建原始集合的析取子集,扩展到推理整个对象集合的一般概念。

考虑到我们并不总是假设这是我们想要解构的子集之一,这个推理原理是如何在coq中捕获的?

考虑以下示例进行演示:

forall n, Nat.Even n => P n.

在这里,我们可以自然地在inversionNat.Even n获取n = 2*x(以及n = 2*x + 1的自动错误消除假设。但是,假设我们有以下内容:

forall n, P n

我如何声明:"让我们考虑even nodd n s"。我是否需要首先证明我们有可判定的forall n : nat, even n \/ odd n?也就是说,引入一个列出所有必需子集的新(局部或全局)引理?什么是最佳实践?

1 个答案:

答案 0 :(得分:2)

事实上,要推断Coq中一类对象的分裂,你需要展示一个分裂它们的算法,除非你想要经典推理(这没有任何问题)。

国际海事组织,一个关键点是获得这样的可判定性假设"免费"。例如,您可以将odd : nat -> bool实现为布尔函数,就像在某些库中完成一样,然后您可以免费获得拆分。

[编辑] 通过将相关案例作为归纳法,您可以使用一些稍微方便的模式匹配技术:

Require Import PeanoNat Nat Bool.

CoInductive parity_spec (n : nat) : Type :=
| parity_spec_odd : odd  n = true -> parity_spec n
| parity_spec_even: even n = true -> parity_spec n
.

Lemma parityP n : parity_spec n.
Proof.
case (even n) eqn:H; [now right|left].
now rewrite <- Nat.negb_even, H.
Qed.

Lemma test n : even n = true \/ odd n = true.
Proof. now case (parityP n); auto. Qed.