Coq 卡在一个非常简单的函数的构造中

Coq 卡在一个非常简单的函数的构造中,coq,Coq,我正在学习Coq。我被困在一个相当愚蠢的问题上(这个问题没有动机,真的很愚蠢)。我想构建一个从[2,+oo]到映射x到x-3的整数集的函数。这应该很简单。。。在我所知道的任何语言中,这都很简单。但不是在Coq。首先,我写(我解释了很多细节,以便有人能解释我对Coq行为的不理解) 我有一个子目标 ============================ forall n : nat, n > 2 -> nat 这意味着Coq需要一个从n>2的证明到整数集的映射。好的我想告诉

我正在学习Coq。我被困在一个相当愚蠢的问题上(这个问题没有动机,真的很愚蠢)。我想构建一个从[2,+oo]到映射x到x-3的整数集的函数。这应该很简单。。。在我所知道的任何语言中,这都很简单。但不是在Coq。首先,我写(我解释了很多细节,以便有人能解释我对Coq行为的不理解)

我有一个子目标

  ============================
   forall n : nat, n > 2 -> nat
这意味着Coq需要一个从n>2的证明到整数集的映射。好的我想告诉它,对于某个整数p,n=3+p,然后返回整数p。我写道:

intros n H.
我得到了上下文/子目标

  n : nat
  H : n > 2
  ============================
   nat
那么我假设我已经证明了,对于某个整数p,n=3+p

cut(exists p, 3 + p = n).
我了解上下文/子目标

  n : nat
  H : n > 2
  ============================
   (exists p : nat, 3 + p = n) -> nat

subgoal 2 (ID 6) is:
 exists p : nat, 3 + p = n
我在上下文中通过

intro K.
我获得:

  n : nat
  H : n > 2
  K : exists p : nat, 3 + p = n
  ============================
   nat

subgoal 2 (ID 6) is:
 exists p : nat, 3 + p = n
稍后我将证明p的存在性。现在我想用精确的p完成证明。所以我需要先做一个

destruct K as (p,K).
我得到了错误信息

错误:不允许对分类集进行案例分析 定义


我被卡住了。

你完全正确!用任何合理的编程语言编写这个函数都应该很容易,幸运的是,Coq也不例外

在您的情况下,只需忽略您提供的证明参数,就可以更轻松地定义函数:

Definition f (n : nat) : nat := n - 3.
然后你可能会想,“但是等一下,自然数在减法下是不闭合的,所以这怎么可能有意义呢?”。在Coq中,自然数的减法不是真正的减法:它实际上被截断了。如果你试着从2中减去,比如说,3,你得到的答案是0:

Goal 2 - 3 = 0. reflexivity. Qed.
这在实践中意味着,你总是可以“减去”两个自然数,然后得到一个自然数,但是为了让这个减法有意义,第一个参数必须大于第二个参数。然后我们得到如下引理(在中提供):

现在,
f
将大于
2
的自然数
n
作为参数(
{x:T | px}
形式是标准库中
sig
类型的语法糖,用于形成类似子集的类型)。通过限制参数类型,我们可以编写一个逆函数
finv
,它接受任意
nat
,并返回另一个大于
2
的数字。然后,我们可以证明引理
fK
finvK
,它们断言
fK
finvK
是彼此相反的


关于
f
的定义,我们使用
val
,这是ssreflect的惯用用法,用于从类型的成员中提取元素,例如
{n | 2
finv
上的
Sub
函数的作用正好相反,它将自然数
n
打包为
2
并返回
{n | 2
元素。在这里,我们非常依赖这样一个事实:
你可能是说{p | 3+p=n}是一个集合?我不知道Coq的规则禁止使用证明来获得计算内容;我天真地认为这就是Coq背后的想法。无论如何,谢谢你的回答,我一看ssreflect库(可能下周)就会重读一遍。@PhilippeGaucher a
Set
在Coq中只是一种特殊的
类型
。控制
类型
道具
之间交互的原因之一是,在提取程序时可以擦除校样。
Goal 2 - 3 = 0. reflexivity. Qed.
le_plus_minus_r : forall n m, n <= m -> n + (m - n) = m
Require Import Ssreflect.ssreflect Ssreflect.ssrfun Ssreflect.ssrbool.
Require Import Ssreflect.ssrnat Ssreflect.eqtype.

Definition f (n : {n | 2 < n}) : nat :=
  val n - 3.

Definition finv (m : nat) : {n | 2 < n} :=
  Sub (3 + m) erefl.

Lemma fK : cancel f finv.
Proof.
move=> [n Pn] /=; apply/val_inj=> /=.
by rewrite /f /= addnC subnK.
Qed.

Lemma finvK : cancel finv f.
Proof.
by move=> n; rewrite /finv /f /= addnC addnK.
Qed.