Coq 在证明定理时循环
在用Debrijn指数和Coq中的代换形式化lambda演算之后,我试图证明以下定理Coq 在证明定理时循环,coq,proof,lambda-calculus,theorem-proving,Coq,Proof,Lambda Calculus,Theorem Proving,在用Debrijn指数和Coq中的代换形式化lambda演算之后,我试图证明以下定理 Theorem atom_equality : forall e : expression , forall x : nat, (beta_reduction (Var x) e) -> (e = Var x). 这些是表达式和beta缩减的定义 Inductive expression : Type := | Var (n : nat) | Abstraction (e : expres
Theorem atom_equality : forall e : expression , forall x : nat,
(beta_reduction (Var x) e) -> (e = Var x).
这些是表达式和beta缩减的定义
Inductive expression : Type :=
| Var (n : nat)
| Abstraction (e : expression)
| Application (e1 : expression) (e2 : expression).
.
.
Inductive beta_reduction : expression -> expression -> Prop :=
| beta_1step (x y : expression) : beta_1reduction x y -> beta_reduction x y
| beta_reflexivity (x : expression) : beta_reduction x x
| beta_transitivity (x y z : expression) : beta_reduction x y -> beta_reduction y z -> beta_reduction x z.
我在试图证明这个定理时陷入了一个循环
Proof.
intro e. induction e.
- intros. inversion H.
在应用这些步骤之后,这些是我必须处理的假设和子目标
3 subgoals
n, x : nat
H : beta_reduction (Var x) (Var n)
x0, y : expression
H0 : beta_1reduction (Var x) (Var n)
H1 : x0 = Var x
H2 : y = Var n
______________________________________(1/3)
Var n = Var x
______________________________________(2/3)
Var n = Var n
______________________________________(3/3)
Var n = Var x
我可以用“反转H0”策略解决第一个子目标,用“自反性”策略解决第二个子目标。然而,当我达到第三个子目标时,这就是我剩下的
1 subgoal
n, x : nat
H : beta_reduction (Var x) (Var n)
x0, y, z : expression
H0 : beta_reduction (Var x) y
H1 : beta_reduction y (Var n)
H2 : x0 = Var x
H3 : z = Var n
______________________________________(1/1)
Var n = Var x
这正是我开始的。我必须证明y只能取H0的Var x的值才是可证明的
(beta_1还原是lambda演算的一步beta还原,beta_还原是它的自反传递闭包)您被卡住了,因为在
H
上反转是不够的。相反,你需要对H
进行一种归纳,为你提供传递性案例中所需的假设,从而让你得出结论。
然而,由于H
的类型是一个归纳谓词,因此对其进行归纳是很困难的。事实上,如果您使用通常的归纳法H.
,Coq将丢失H
类型中有关指数的所有信息,尤其是Var x
类型。这将使您的验证尝试失败
相反,您可以使用的是依赖于依赖归纳
策略(您需要要求导入程序。平等
才能使用此策略)。这种策略会自动处理索引不是变量的归纳谓词。在这里,你可以从介绍e n H.依赖归纳H.
开始你的证明,其余的应该很简单
通常,当您在归纳数据类型(例如
表达式
)上定义归纳谓词(例如beta_reduction
)时,您希望使用这些归纳谓词(此处H
)使用假设,直接对谓词进行归纳(使用依赖归纳
)正如我们在这里所做的那样,它非常强大。特别是,它专门说明了数据类型的哪些构造函数可以出现在归纳假设中,因此在某种程度上同时对数据类型执行归纳。您被卡住了,因为在H
上反转是不够的。相反,你需要对H
进行一种归纳,为你提供传递性案例中所需的假设,从而让你得出结论。
然而,由于H
的类型是一个归纳谓词,因此对其进行归纳是很困难的。事实上,如果您使用通常的归纳法H.
,Coq将丢失H
类型中有关指数的所有信息,尤其是Var x
类型。这将使您的验证尝试失败
相反,您可以使用的是依赖于依赖归纳
策略(您需要要求导入程序。平等
才能使用此策略)。这种策略会自动处理索引不是变量的归纳谓词。在这里,你可以从介绍e n H.依赖归纳H.
开始你的证明,其余的应该很简单
通常,当您在归纳数据类型(例如
表达式
)上定义归纳谓词(例如beta_reduction
)时,您希望使用这些归纳谓词(此处H
)使用假设,直接对谓词进行归纳(使用依赖归纳
)正如我们在这里所做的那样,它非常强大。特别是,它专门说明了数据类型的哪些构造函数可以出现在归纳假设中,从而在某种程度上同时对数据类型进行归纳。@Meven的回答很好地解释了错误,并给出了一个很好的解决方案。如果您想在不使用依赖归纳法的情况下完成此操作,您可以自己记住丢失的信息
Proof.
(beta_reduction (Var x) e) -> (e = Var x).
intros e x H.
remember (Var x) as q eqn:Hq.
induction H; rewrite Hq in *.
- inversion H.
- reflexivity.
- rewrite IHbeta_reduction1 in IHbeta_reduction2.
apply IHbeta_reduction2.
reflexivity.
reflexivity.
Qed.
@梅文的回答很好地解释了问题所在,并给出了一个很好的解决方案。如果您想在不使用依赖归纳法的情况下完成此操作,您可以自己记住丢失的信息
Proof.
(beta_reduction (Var x) e) -> (e = Var x).
intros e x H.
remember (Var x) as q eqn:Hq.
induction H; rewrite Hq in *.
- inversion H.
- reflexivity.
- rewrite IHbeta_reduction1 in IHbeta_reduction2.
apply IHbeta_reduction2.
reflexivity.
reflexivity.
Qed.
请您也添加
beta_1还原的定义,使您的代码成为a。请您也添加beta_1还原的定义,使您的代码成为a。这几乎就是依赖归纳法
在幕后自动化的魔力。的确,这就是依赖归纳法
在幕后实现自动化的神奇之处。