我在Coq中查询了归纳定义的关系eq
。考虑Coq中eq
的以下定义:
Inductive eq (A : Type) (x : A) : A -> Prop := eq_refl : x = x
这是一个归纳定义的关系,就像le
(<=
)一样。因此,我应该能够对这种类型的任何证据进行案例分析。
但是,当我尝试证明以下结果时,我无法成功。
Lemma true_num: forall m :nat, forall x y: m=m, x=y.
Proof. intros. destruct x.
(// Error: Abstracting over the terms "m" and "x" leads to a term
fun (m0 : nat) (x0 : m0 = m0) => x0 = y
which is ill-typed.
Reason is: Illegal application:
The term "@eq" of type "forall A : Type, A -> A -> Prop"
cannot be applied to the terms
"m0 = m0" : "Prop"
"x0" : "m0 = m0"
"y" : "m = m"
The 3rd term has type "m = m" which should be coercible to
"m0 = m0". )
我无法解码此错误。
m=m
的唯一证据应该是@eq_refl nat m
,因为eq_refl
是唯一的构造函数。因此,应该能够通过案例分析来证明x
和y
的平等。
这种推理有什么问题?
答案 0 :(得分:2)
错误是由destruct
的工作方式引起的,回想一下该策略试图建立一个匹配语句,并且为了做到这一点,它有一些启发式方法可以将依赖假设置于上下文中。
特别是,在这种情况下,它试图抽象变量m
,它是eq
中y : m = m
归纳的索引;但y
未被置于上下文中,因此错误为m != m0
[m0
为抽象的m
]。您可以通过执行“不太智能”的匹配来解决该问题,这不会修改m
:
refine (match x with | @eq_refl _ _ => _ end).
但通常,最好的解决方案是将错误假设纳入范围:
revert y; destruct x.
另一方面,为了证明你的目标,简单的模式匹配是不够的,正如其他优秀答案所指出的那样。我解决像你这样的目标的首选实用方法是使用库:
From mathcomp Require Import all_ssreflect.
Lemma true_num (m : nat) (x y : m = m) : x = y.
Proof. exact: eq_irrelevance. Qed.
在这种情况下,nat
类型的正确边条件由图书馆的机器自动推断。
答案 1 :(得分:1)
m = m的唯一证据应该是@eq_refl nat m,因为eq_refl是唯一的构造函数
没有。你的定理恰好是正确的,因为你在讨论nat
的平等,但是如果用nat
替换Type
并替换{{{}},那么你的推理也同样(或很差)。带有nat
的1}}使得该定理无法生成。
问题在于,通过反射性证明,系列是自由生成的。因此,由于Coq中的所有内容都以正确的方式尊重相等(这就是我有点模糊),以证明一个族中所有相等证明的属性(即Type
的所有证据都是一些固定的x = y
和用于所有 x
),它足以证明生成器的属性,反射性证明。但是,一旦你修复了两个端点,可以这么说,你就不再拥有这个属性了。换句话说,y
的归纳原则实际上是eq
的归纳原则,而不是{ y | x = y }
。同样,向量的归纳原则(长度索引列表)实际上是x = y
的归纳原则。
要解码错误消息,尝试手动应用{ n & Vector.t A n }
的归纳原则可能会有所帮助。归纳原则指出:给定类型eq
,术语A
和属性x : A
,以证明P : forall y : A, x = y -> Prop
任何给定的P y e
和任何证据{ {1}},只需证明y : A
即可。 (要了解为什么这有意义,请考虑非依赖版本:给定类型e : x = y
,术语P x eq_refl
和属性A
,适用于任何x : A
和任何证据P : A -> Prop
,要证明y : A
,就足以证明e : x = y
。)
如果您尝试手动应用此功能,您会发现当您尝试引入第二个相等证明时,无法构建类型良好的函数P y
。
有一篇优秀的博客文章在此更深入地解释了这一点:http://math.andrej.com/2013/08/28/the-elements-of-an-inductive-type/