为什么不能对结论中使用的术语进行归纳?

Why is it impossible to perform induction on a term that is used in conclusion?

假设以下特定场景。

我们有一个相等的定义:

Inductive eqwal {A : Type} (x : A) : A -> Prop :=
    eqw_refl : eqwal x x.

还有 peano nats:

Inductive nawt : Prop :=
    | zewro : nawt
    | sawc  : nawt -> nawt.

我们在nats上定义加法:

Fixpoint plaws (m n : nawt) : nawt :=
    match m with
      | zewro => n
      | sawc m' => sawc (plaws m' n)
    end.

现在我们要证明零从右到右是中性的。求和:

Theorem neutral_r : forall n : nawt, eqwal (plaws n zewro) n.

可悲的是,以下证明的最后一行说“错误:结论中使用了 n。”。

Proof.
intros.
induction n. - this is the culprit

官方文档中没有太多关于错误的信息,我有点困惑-为什么会出现这个错误?

使用标准库,我可以很容易地证明定理:

Theorem neutral_r : forall n : nat,
  n + 0 = n.
Proof.
  induction n; try reflexivity.
  cbn; rewrite IHn; reflexivity.
Qed.

问题是您定义 nawt 时使用排序 Prop 而不是 TypeSet。默认情况下,为命题生成的归纳原理不允许我们证明任何关于这些命题的证明。考虑为 nawt:

生成的默认归纳原理
Check nawt_ind.
> nawt_ind : forall P : Prop, P -> (nawt -> P -> P) -> nawt -> P

因为 nawt_ind 量化超过 Prop,而不是超过 nat -> Prop,我们不能用它来证明你的目标。

解决方案是设置一些选项来更改 Coq 的默认行为,如以下脚本所示。

Inductive eqwal {A : Type} (x : A) : A -> Prop :=
    eqw_refl : eqwal x x.

Unset Elimination Schemes.

Inductive nawt : Prop :=
    | zewro : nawt
    | sawc  : nawt -> nawt.

Scheme nawt_ind := Induction for nawt Sort Prop.

Set Elimination Schemes.

Fixpoint plaws (m n : nawt) : nawt :=
    match m with
      | zewro => n
      | sawc m' => sawc (plaws m' n)
    end.

Theorem eqwal_sym {A : Type} (x y : A) : eqwal x y -> eqwal y x.
Proof. intros H. destruct H. constructor. Qed.

Theorem neutral_r : forall n : nawt, eqwal (plaws n zewro) n.
Proof.
intros. induction n as [|n IH]; simpl.
- constructor.
- apply eqwal_sym in IH. destruct IH. constructor.
Qed.

Elimination Schemes 选项使 Coq 自动生成数据类型和命题的归纳原理。在此脚本中,我只是将其关闭,并使用 Scheme 命令为 nawt 生成正确的归纳原理。为了让 induction 策略起作用,重要的是给这个原则命名 nawt_ind:这是 Coq 生成的默认名称,也是 induction 寻找的那个打电话。

也就是说,我通常建议不要在 Prop 中定义一种自然数,而不是在 Type 中定义,因为 Coq 对如何使用存在于 [=13 中的事物施加了限制=].例如,无法证明 zewro 不同于 sawc zewro