我暂时遇到了一个问题,为此我得出了一个较小的独立示例:
Axiom f : nat -> Set.
Goal forall (n : nat) (e : n = n) (x : f n),
match e in _ = _n return f _n -> Prop with
| Logic.eq_refl => fun v : f n => v = x
end x.
现在,如果您尝试destruct e
,则会收到以下错误消息:
Error: Abstracting over the terms "n0" and "e" leads to a term
"fun (n0 : nat) (e : n0 = n0) =>
forall x : f n0,
match e in (_ = _n) return (f _n -> Prop) with
| Logic.eq_refl => fun v : f n0 => v = x
end x" which is ill-typed.
在我挠了一会儿之后,我无法弄清楚那个词中的错误类型......所以我试过了:
Definition illt :=
fun (n : nat) (e : n = n) =>
forall x : f n,
match e in _ = _n return f _n -> Prop with
| Logic.eq_refl => fun v : f n => v = x
end x.
Coq在类型forall n : nat, n = n -> Prop
接受它。
那么,这个错误信息有什么问题,我怎样才能解决/调整我的初始目标?
BTW这是coq8.3。如果这是8.4中修复的问题,请告诉我,我的道歉! :)
编辑:要解决Robin Green的评论,以下是错误消息的Set Printing All
版本:
Error: Abstracting over the terms "n0" and "e" leads to a term
"fun (n0 : nat) (e : @eq nat n0 n0) =>
forall x : f n0,
match e in (@eq _ _ _n) return (f _n -> Prop) with
| eq_refl => fun v : f n0 => @eq (f n0) v x
end x" which is ill-typed.
这是一个很好的术语,没有任何暗示。
答案 0 :(得分:3)
以下是该问题的可能解释。在构造模式匹配构造时会发生什么,也可以用定理来描述。以下是我对你案例中使用的定理的看法。
Check eq_rect.
eq_rect
: forall (A : Type) (x : A) (P : A -> Type),
P x -> forall y : A, x = y -> P y
因此,当在相等上进行模式匹配时,您必须提供在任何值 y
上参数化的公式P,该公式恰好等于x
。直观地说,您应该能够用apply eq_rect
替换模式匹配表达式,但是应该出现的属性P超出了Coq可以猜到的范围,因为每次出现x
公式必须在f n
类型中,并且不能只在f m
m = n
类型中。错误信息没有说明,这可能是一个错误。
为了执行你的证明,我建议使用这样一个事实:在某些类型的类中,相等证明是唯一的,nat
属于这样的类。这在文件Eqdep_dec。
Require Eqdep_dec Arith.
现在你的证据非常容易。
Goal forall n (x : f n) (e : n = n),
match e in _ = _n return f _n -> Prop with
| Logic.eq_refl => fun v : f n => v = x
end x.
intros n x e; replace e with (eq_refl n).
reflexivity.
apply Eqdep_dec.UIP_dec, eq_nat_dec.
Qed.
现在,这种解决方案可能会令人不满意。这个UIP_dec
来自哪里? UIP代表身份证明的唯一性,遗憾的是,并不保证所有任意类型都具有此属性。对于可以判定相等性的所有类型(由UIP_dec
表示),例如nat
,保证可以保证。