用eexists构造Coq中的记录项
假设在某个类型上有一个二元关系用eexists构造Coq中的记录项,coq,Coq,假设在某个类型上有一个二元关系R Variable A : Type. Variable R : A -> A -> A -> A -> A -> A -> A -> A -> A -> A -> Prop. Inductive X : Prop := | X_intro : forall a0 a1 a2 a3 a4 a5 a6 a7 a8 a9, R a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 -> X.
R
Variable A : Type.
Variable R : A -> A -> A -> A -> A -> A -> A -> A -> A -> A -> Prop.
Inductive X : Prop :=
| X_intro : forall a0 a1 a2 a3 a4 a5 a6 a7 a8 a9,
R a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 -> X.
Record Y : Prop :=
{ a0 : A; a1 : A; a2 : A; a3 : A; a4 : A;
a5 : A; a6 : A; a7 : A; a8 : A; a9 : A;
RY : R a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 }.
X
和Y
是稍有不同的命题,它们都断言R
包含大约10个A
类型的术语
Variable A : Type.
Variable R : A -> A -> A -> A -> A -> A -> A -> A -> A -> A -> Prop.
Inductive X : Prop :=
| X_intro : forall a0 a1 a2 a3 a4 a5 a6 a7 a8 a9,
R a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 -> X.
Record Y : Prop :=
{ a0 : A; a1 : A; a2 : A; a3 : A; a4 : A;
a5 : A; a6 : A; a7 : A; a8 : A; a9 : A;
RY : R a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 }.
由于X
和Y
断言相同的东西,因此证明X->Y
应该很容易。例如,我们可以通过显式构造Y
的证明来实现
Theorem XY : X -> Y.
inversion 1. exists a0 a1 a2 a3 a4
a5 a6 a7 a8 a9. apply H0. Qed.
但这似乎没有必要。最后一个命题由倒置
on premise得出,它完全决定了10个术语,所以我们不必把它们的名字拼出来。我们可以推迟他们与现存者的认同,并在以后统一他们
Theorem XY' : X -> Y.
intro. eexists. inversion H. apply H0.
但统一在这里失败了。这就是我在应用H0之前的目标:
H0 : R a0 a1 a2 a3 a4 a5 a6 a7 a8 a9
======================== ( 1 / 1 )
R ?46 ?47 ?48 ?49 ?50 ?51 ?52 ?53 ?54 ?55
R
的所有参数都是不确定的,因此应该可以将-46
与a0
统一,将-47
与a1
统一,依此类推。为什么会失败?您收到的错误消息大致如下:
无法将“?a0”与“a0”统一(无法实例化“?a0”,因为“a0”
不在其范围内)
这是一个相当常见的错误。让我用一个简单的例子来解释
让我们从定义一个归纳数据类型开始,该类型封装了类型为a
的值:
Variable A : Type.
Inductive Box :=
| elem : A -> Box.
接下来,让我们定义一个关于此数据类型的定理,该定理指出,如果有一个方框,则存在一个与方框中的内容相等的元素:
Theorem boxOk (b:Box) : exists a, match b with elem a' => a = a' end.
我们可以用你的方式证明这一点:
eexists.
destruct b.
Fail reflexivity.
Restart.
但是reflectivity
失败,并显示可怕的错误消息:
无法将“?a”与“a”统一(无法实例化“?a”
因为“a”不在其作用域中:可用参数为
“要素a”)
那么这里发生了什么?这些战术构成的术语如下所示:
ex_intro _ ?a (match b with elem a => eq_refl end).
match b with elem a => (ex_intro _ ?a eq_refl) end.
您现在要求Coq用a
填写?a
,因为a
未在?a
的范围内定义,因此无法使用。此错误最常见的问题是调用eexists
太早
因此,我们应该先destruct
,然后调用eexists
。它的工作原理是:
destruct b.
eexists.
reflexivity.
Qed.
这些战术构成的术语如下所示:
ex_intro _ ?a (match b with elem a => eq_refl end).
match b with elem a => (ex_intro _ ?a eq_refl) end.
现在a
在?a
的范围内,可以很容易地填写
在您的示例中,您应该执行以下操作(这实际上是您在手册校对中所做的操作)
将来:请尽量减少您的测试用例,例如,我相信三元关系就足够了。此外,请不要参考自动生成的名称,如
H0
。这使得不同Coq版本的用户很难帮助您。