Coq:目标只是一种类型(当使用带有不必要参数的定理时)

Coq: goal is just a type (when using theorems with unnecessary arguments)

我在 Coq 中发现了一个奇怪的怪癖。当你有一个带有不必要参数的定理时,就会发生这种情况,我们对这个定理使用 rewrite。例如,考虑以下代码片段。

Theorem foo : forall (k : nat) (x : bool), k=0+k.
Proof. reflexivity. Qed.

Theorem bar : forall (k : nat), 0+k=k.
Proof.
  intros k. rewrite foo. reflexivity.
  (* At this point, the goal is just "bool"! *)
Abort.

在这个例子中,foo 有一个多余的参数 x。然后,当我在 bar 的证明中使用 rewrite foo 时,它会生成一个目标,它只是读取“bool”。

我的第一个问题是:为什么会产生这样的目标?

其次,我发现可以使用 assumption 策略来完成此目标。但是,这并没有真正说明目标是如何解决的。还有什么战术可以用来完成这样的目标?

目标 bool 是在您应用 rewrite foo. 策略时创建的。 此时,您要求 Coq 找到表达式 ek : natex : bool,以便 foo ek ex 的左侧出现在目标中。使用合一,Coq 推断出 ek := k 是一个合理的选择,但是它没有得到 ex 的任何信息,因为变量 x 没有出现在 foo 的陪域中。因此,它创建了一个新目标,以便您作为用户可以将缺少的参数填充到 foo.

现在,由于该参数实际上未被使用,您可以通过多种方式实现该目标:您可以提供具体的布尔值 exact true.exact false,将其留给自动化 constructor. 或使用您在上下文中拥有的任何布尔值(实际上我对假设的行为感到有点惊讶是您的上下文已关闭,如您的示例所示)。

您还可以在 Coq 创建目标之前提供参数,例如使用 rewrite (foo k true).

kyo 很好地回答了您的问题,但我记得对此感到困惑,所以这里有一些额外的背景信息:

在 Coq 中,说 X 成立(比如,这是一个目标,现在它被证明了)等同于说存在一个 X 类型的项(即 X有人居住)。当X恰好是一个逻辑公式时(即当X : Prop时),我们期望找到它作为目标并用策略来证明它。当 X 碰巧是其他任何东西时(例如,bool),我们希望找到它作为一个术语并在定义中使用它。但是,没有什么可以阻止您在定义中使用逻辑公式(通常导致依赖类型),通过显式提供证明而不是使用策略(例如 eq_refl : 0 = 0)来证明逻辑公式,或者证明 [=16] =] 居住在使用战术。

这种区别仍然有用,因为我们通常不关心 哪个 证明被用来证明给定的定理,但我们经常关心哪个类型的术语 bool 我们掌握了(虽然不是在你的例子中)。