Coq 在证明定理时循环

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

在用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 : 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。这几乎就是
依赖归纳法
在幕后自动化的魔力。的确,这就是
依赖归纳法
在幕后实现自动化的神奇之处。