什么是子目标“ nat”

时间:2019-05-12 20:12:43

标签: coq

在尝试证明引理时,我遇到这样一种情况,仅剩一个子目标,即nat

1 subgoal
...
______________________________________(1/1)
nat

我对这意味着什么感到困惑。 我实际上需要证明什么?是否有关于该主题的任何文档(对Coq的问题很难谷歌搜索)?

我不想分享实际的引理,因为这是一项任务。基本上,我试图证明一个归纳定义是这样的:

Inductive indef : deftype -> Prop :=
| foo x : indef (construct_0 x)
| bar a : (forall x, some_predicate x a) -> indef (construct_1 a).

作为证明,我可以证明(forall x : nat, some_predicate x a)。虽然仅为some_predicate定义了谓词nat,但我怀疑问题与{{1}的定义中未明确指出x的类型有关。 }}。 这可能是我看到indef子目标`的原因吗?

2 个答案:

答案 0 :(得分:1)

这里是一个示例,但我认为它不适合您的用例。我有一个产生逻辑语句证明的函数,但是此函数需要一个整数。该整数实际上对于证明没有用,但是由于键入原因,对该函数的任何使用都将需要该整数。

Definition my_fun (n : nat) : True := I.

Lemma dummy_setup : True.
Proof. apply my_fun.

因此,在这一点上,函数my_fun需要一个nat类型的参数,该参数在其他任何地方都没有使用,但是它必须存在。 Coq系统处理此参数,就好像它是逻辑目的所需的证明一样,因此它要求您提供此类型的元素。通常,这表明您对函数的设计方式很差,并且它们使用了不使用的参数。避免这种情况的方法是回到引理,并确保它们没有无用的论点。

这是另一个例子。 my_trans引理采用了无用的论点。

Require Import Arith.
Lemma my_trans : forall x y z t, x <= y -> y <= z -> x <= z.
Proof.  intros x y z; apply (le_trans x y z). Qed.

使用此引理时,会弹出对额外参数的需求。证明机器只希望我证明存在某个自然数来填充该点。

Lemma toto x y z : y <= z -> x <= y -> x <= z.
intros h1 h2; revert h2 h1; apply my_trans.

您的问题的解决方案是查看定理,该定理的应用触发了该nat目标的出现,并清理了该定理以删除实际上未使用的通用量化变量。

答案 1 :(得分:0)

只要引理的结果类型为Prop,Coq就不会真正在证明过程中填充子目标。 通过填充子目标,您实际上是在提供该目标类型的值。

考虑一下:

如果遇到目标True,则可以通过提供类型为True的值I来明确地实现目标。您可以用战术语言写:

1 subgoal
______________________________________(1/1)
True

exact I.     (* explicit way, or  *)
constructor. (* less explicit way *)

No more subgoals.

拥有nat类型的目标是一回事。显然,O是类型nat的值(12432523547835之类的自然数也是),因此您可以用它来实现目标:

1 subgoal
______________________________________(1/1)
nat

exact O.              (* this obviously works *)
exact 12432523547835. (* this does work too   *)

No more subgoals.

可能无关,但是目标或类型nat或任何其他类型在“以证明模式编写定义”的上下文中完全有意义。例如一个函数

Definition double (x : nat) : nat := x + x.

可以用这种方式定义(但是不要这样做,除非目标类型是复杂的从属类型,并且结果不能以经典的方式轻易地得出):

Definition double (x : nat) : nat.

1 subgoal
x : nat
______________________________________(1/1)
nat

exact (x + x).  (* Fill the goal with desired value *)

No more subgoals.

Defined.      (* Use this instead of Qed to allow Coq to unfold the definition *)
Print double. (* Checking that the function body is correct *)

double = fun x : nat => x + x
     : nat -> nat

我想我曾经在为一个可靠的递归函数编写证明时遇到过类似的情况,并且我以某种错误的假设(即所定义的函数,实际上不是假设)对目标进行了应用。但是我仍然可以完成证明,并且定义的功能可以按预期工作。