当Coq将函数扩展为目标的一部分时,这意味着什么?

当Coq将函数扩展为目标的一部分时,这意味着什么?,coq,Coq,我试图解决以下定理,但在最后一个简单问题上遇到了困难。: Lemma nonzeros_app : forall l1 l2 : natlist, nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2). Proof. intros l1 l2. induction l1 as [| n' l' IHl']. -simpl. reflexivity. -simpl. Qed. 在这一点上,Coq将目标从: 1 subgoal

我试图解决以下定理,但在最后一个
简单问题上遇到了困难。

Lemma nonzeros_app : forall l1 l2 : natlist,
  nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2).
Proof.
  intros l1 l2. induction l1 as [| n' l' IHl'].
  -simpl. reflexivity.
  -simpl. 
Qed.
在这一点上,Coq将目标从:

1 subgoal (ID 170)

  n' : nat
  l', l2 : natlist
  IHl' : nonzeros (l' ++ l2) = nonzeros l' ++ nonzeros l2
  ============================
  nonzeros ((n' :: l') ++ l2) = nonzeros (n' :: l') ++ nonzeros l2
致:

这对我来说是完全神秘的。当Coq将函数的定义粘贴到我的目标中时,这意味着什么?我该拿这个怎么办


问题的上下文:

有人告诉我解决办法是:

Lemma nonzeros_app : forall l1 l2 : natlist,
  nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2).
Proof.
  intros l1 l2. induction l1.
  - simpl. reflexivity.
  - simpl. { induction n.
             - ...
             - ... }
Qed.

这让我想理解为什么他们在
n
上使用归纳法,因为我觉得在那里永远不会使用归纳法。所以我问,为什么?但我意识到,在我可以问这个问题之前,我甚至不理解证明状态,因为它似乎只是将一个函数复制粘贴到证明状态(这对我来说毫无意义)。因此,在我问为什么要在这里使用归纳之前,我必须问一下,在这之前,证明状态是什么,也许这会让我们明白为什么在
n

上使用归纳,我假设你已经用以下方式(或类似方式)定义了
非零

因此,
非零
是递归的,在
l
上结构递减。 Coq的
siml
策略采用了一种启发式方法,在这种方法中,如果不动点的定义应用于一个以构造器作为首符号的术语,它就会展开不动点的定义。 在您的例子中,例如,
非零(n'::l')
,常量
非零
后面跟着一个由构造函数构成的术语,
Cons
(=
)。Coq执行所谓的“增量缩减”,用其定义替换出现的
非零
。由于该定义是一个
匹配
,因此您将得到一个
匹配
作为您的新术语。进一步的替换确实使它简化了一点,但不能消除两种情况:一种是零头,另一种是非零头

非零((n':(l')++l2)的出现也会发生同样的情况,它首先被简化为非零(
(n':(l'++l2))
,因此,参数的开头也是
Cons

如果要避免在简化时暴露
match
表达式,可以在
非零的定义之后放置以下指令:

Arguments nonzeros l : simpl nomatch.
这特别告诉
siml
,如果最终会在更改位置暴露
匹配项,则应避免扩展术语

至于你朋友在这里使用的
归纳法
:它用于强制将一个案例拆分为
n'
,这样每个案例(
n'=0
n'=S
)都可以单独处理。事实上,这里不需要归纳法。一个简单的案例拆分(
case n'
)也可以做到这一点。

交叉发布:
Require Import List.
Import ListNotations.


Definition natlist := list nat.

Fixpoint nonzeros (l : natlist) :=
  match l with
  | [] => []
  | 0 :: xs => nonzeros xs
  | x :: xs => x :: nonzeros xs
  end.
Arguments nonzeros l : simpl nomatch.