我想弄清楚让我感到惊讶的事情。请考虑以下两个定义。
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).
我的第一个直觉是他们说同样的话(但是否定了)。但是,@Arthur Azevedo De Amorim表明它们并不完全等效(or see here)。如果~ NoDup l -> Dup l
则必须是forall (a b:A), ~ a <> b -> a = b
的情况。因此,如果在陈述一个证明目标时使用A
而不是~ NoDup
,则Dup
类型的额外假设会被偷偷摸摸。
我试图找出引入这个额外假设的地方,以获得所发生事件的心理模型,所以下次我会亲自看到它。我目前的解释是
~ In x l
的{{1}}参数负责,因为NoDup_cons
与列表中的第一个元素不同,列表中的第二个元素等时,才能创建~ In x l
个术语因此,当我破坏术语om x
时,我得到的术语NoDup (_::_)
只能为~ In _ _
必须保留的A
类型创建。< / p>
问:这是一种好的“非正式”思考方式,还是有更好的方式来理解它,所以我不会再陷入这个陷阱了?
此外,我发现Coq library contains NoDup
而不是~ a <> b -> a = b
,因此可能有些lemma比他们需要的要弱,因为它们是使用Dup
代替{{1}制定的}。但是,它们可以使用NoDup
来制定Dup
。
答案 0 :(得分:3)
我认为从这个例子中得出的教训是,在思考直觉主义逻辑中的否定时,你需要更加小心。特别是,你的陈述&#34;他们说同样的事情(但否定了)&#34;在经典逻辑中有意义:它表示等效语句P <-> ~Q
或~P <-> Q
。但是,在直觉逻辑中,这两个语句 not 等价,所以你必须更具体地说明这两个语句中的哪一个(如果有的话)实际上是真的。
在这种情况下, 为真,NoDup l
相当于~ Dup l
。什么是不一般是Dup l
是一个正常的命题(回想一下如果P
,命题~~P -> P
被称为正常,在这种情况下它是&#39}很容易得出结论P <-> ~~P
)。因此,~ NoDup l
相当于~~ Dup l
,它通常比Dup l
严格弱于声明。
考虑两者之间差异的一种可能方式是:从Dup l
的具体证明中,可以提取一对索引,使得l
的相应条目相等(由于从Prop
到Type
的消除限制,在字面上不是Coq中的函数,但你肯定可以证明存在这样一对索引的引理)。另一方面,~ NoDup l
的具体证据只是提供了一种方法来获取NoDup l
的声称证据,并从中得出一个矛盾 - 从中你无法提取任何特定的一对指数。
(我同意,标准库只有NoDup
而不是Dup
,这有点奇怪。)