在归纳命题中使用记忆会在Coq中产生“错误类型”错误

时间:2014-06-28 14:18:27

标签: coq induction

以下是归纳&自然数均匀性的计算定义。

Inductive ev : nat -> Prop :=
  | ev_0 : ev O
  | ev_SS : forall n:nat, ev n -> ev (S (S n)).

Definition even (n:nat) : Prop := 
  evenb n = true.

证明一方意味着另一方。

Theorem ev__even : forall n,
  ev n -> even n.
intros n E.
induction E as [ | n' E' ]. 
reflexivity. apply IHE'. Qed.

我一开始并没有多想这个证据,但仔细观察我发现了一些令人不安的事情。问题是在reflexivity步骤之后,我希望看到上下文

1 subgoal
n' : nat
E : ev (S (S n'))
E' : ev n'
IHE' : ev n' -> even n'
====================================================================== (1/1)
even (S (S n'))

但我真正得到的是

1 subgoal
n' : nat
E' : ev n'
IHE' : even n'
====================================================================== (1/1)
even (S (S n'))

虽然这个定理仍然是可证明的,但看到假设神秘地消失是令人不安的。我想知道如何获得我最初预期的背景。从网络搜索中我了解到,这是在Coq中对构造术语进行归纳的一般问题。 One proposed solution on SO建议使用remember关于假设的策略。但是当我在这个证明中尝试时,

Theorem ev__even : forall n,
  ev n -> even n.
intros n E.
remember E.
induction E as [ | n' E' ]. 

我在induction步骤收到以下错误消息。

Error: Abstracting over the term "n" leads to a term
"fun n : nat => forall e : ev n, e = E -> even n" which is ill-typed.

我真的不明白。我认为问题是E有一个自由变量,但在这种情况下我会被卡住,因为没有介绍E而没有引入{{1} }}。 (n会将generalize dependent n与它一起推广)

有没有办法获得最初预期的背景?

2 个答案:

答案 0 :(得分:3)

为了有用,归纳策略试图概括所有依赖于你正在进行归纳的事物的变量,以及依赖于其类型索引的事物。在您的情况下,这意味着概括n,新生成的证明e : ev n和相等e = E。但是,它并没有概括E本身,因为为命题自动生成的归纳原则忽略了证明论证。不幸的是,这意味着泛化将是错误的,并且你的直觉是正确的:因为E没有用n推广,它的类型将提到不同的数字,这将使等式{{ 1}}不好的。

答案 1 :(得分:2)

我不明白induction策略在这里做了什么。 每当我不明白策略是什么时,我就会尝试自己编写证明术语。 如果您手动调用归纳原理,则可以保留原始假设:

Theorem ev__even : forall n, ev n -> even n.
  intros n E.
  refine (ev_ind even _ _ n E).
  - reflexivity.
  - intros n' E' IH.
    apply IH.
Qed.

这是导入的第二种情况中的上下文:

  n : nat
  E : ev n
  n' : nat
  E' : ev n'
  IH : even n'
  ============================
   even (S (S n'))

假设

Fixpoint evenb (n:nat) : bool :=
  match n with
  | O        => true
  | S O      => false
  | S (S n') => evenb n'
  end.