Coq 直觉定义中令人惊讶的隐含假设

Coq 直觉定义中令人惊讶的隐含假设,coq,Coq,我想弄明白一些让我吃惊的事情。考虑以下两个定义: Require Import List. Variable A:Type. Inductive NoDup : list A -> Prop := NoDup_nil : NoDup nil | NoDup_cons : forall x l, ~ In x l -> NoDup l -> NoDup (x :: l). Inductive Dup : list A -> Prop := Dup_hd : fo

我想弄明白一些让我吃惊的事情。考虑以下两个定义:

Require Import List.
Variable A:Type.

Inductive NoDup : list A -> Prop :=
  NoDup_nil : NoDup nil
| NoDup_cons : forall x l, ~ In x l -> NoDup l -> NoDup (x :: l).

Inductive Dup : list A -> Prop :=
  Dup_hd : forall x l, In x l -> Dup (x :: l)
| Dup_tl : forall x l, Dup l  -> Dup (x :: l).
我的第一直觉是他们说了同样的话(但否定了)。然而,研究表明,它们并不完全相同()。如果
~NoDup l->Dup l
,则必须是
对于all(ab:a),~ab->a=b
。因此,如果在陈述自己的证明目标时使用
~NoDup
而不是
Dup
,那么对类型
A
的额外假设就会潜入其中

我试图找出这个额外的假设是在哪里引入的,以获得发生了什么的心理模型,所以我下次会亲自去看。我目前的解释是

  • NoDup\u cons
    ~In x l
    参数负责,因为
  • 只有当能够证明某个
    x
    与列表中的第一个元素、第二个元素等不同时,才能创建
    ~In x l
    术语
因此,当我销毁一个术语om type
NoDup(::)
时,我会在u中得到一个术语
~In,它只能为一个类型
a
创建,而
~ab->a=b
必须保持该类型

问:这是一种“非正式”的思考方式,还是有更好的方式来理解它,这样我就不会再次落入那个陷阱


另外,我发现and不是
Dup
,所以可能有些引理比它们需要的弱,因为它们是用
NoDup
而不是
Dup
来表示的。但是,它们可以用
Dup
来表示,因为
~Dup l->NoDup l
我认为从这个例子中可以学到的教训是,在直觉逻辑中考虑否定时需要更加小心。特别是,您的语句“他们说相同的事情(但否定)”在经典逻辑中是有意义的:它表示等价语句
P~Q
~pq
。然而,在直觉逻辑中,这两种说法是不等价的,所以你必须更具体地说明这两种说法中哪一种(如果有)是真的

在这种情况下,
NoDup l
确实相当于
~Dup l
。通常不正确的是
Dup l
是一个正常命题(回想一下,如果
~~P->P
,命题
P
称为正常命题,在这种情况下很容易得出结论
P~~P
)。因此,
~NoDup l
相当于
~Dup l
,一般来说,这是一个比
Dup l
更弱的语句

考虑两者之间差异的一种可能方式是:从
Dup l
的具体证明中,可以提取一对索引,使
l
的对应条目相等(由于从
Prop
消除到
Type
的限制,在Coq中不是字面上的函数,但你可以肯定地证明存在这样一对索引的引理).另一方面,
~NoDup l
的具体证明只是提供了一种方法,可以采用声称的
NoDup l
证明,并从中推导出一个矛盾-从中你不一定能提取任何特定的索引对

(我同意标准库只有
NoDup
而没有
Dup
,这有点奇怪。)

嗯,
NoDup l
确实等同于
~Dup l
——只是
Dup l
一般来说不是一个正常的命题,所以
~NoDup l~~Dup l
并不等同于
Dup l