Coq中记录成员的入职培训?

Coq中记录成员的入职培训?,coq,coq-tactic,Coq,Coq Tactic,考虑对记录成员进行归纳的一个简单示例: Record Foo : Type := mkFoo { foo: nat }. Definition double (f: Foo) : Foo := mkFoo (2 * foo f)%nat. Theorem double_doubles: forall (f: Foo), foo (double f) = (2 * foo f)%nat. Proof. intros. induction (foo f). (* How

考虑对记录成员进行归纳的一个简单示例:

Record Foo : Type := mkFoo { foo: nat }.

Definition double (f: Foo) : Foo :=
  mkFoo (2 * foo f)%nat.


Theorem double_doubles: forall (f: Foo),
    foo (double f) = (2 * foo f)%nat.
Proof.
  intros.
  induction (foo f).
  (* How do I prevent this loss of information? *)
  (* stuck? *)
Abort.


Theorem double_doubles: forall (f: Foo),
    foo (double f) = (2 * foo f)%nat.
Proof.
  intros.
  destruct f.
  (* destruct is horrible if your record is large / contains many things *)
  induction foo0.
  simpl. auto.
  intros. simpl. auto.
Qed.
入职培训(foo f)
中,我被目标所束缚
foo(双f)=2*0

我不知何故丢失了我正在对
foo f
进行归纳的信息(我没有假设
foo f=0

然而,
destructf
并不令人满意,因为我有~5个成员记录,当展开时,在假设部分看起来非常丑陋


非常感谢您的帮助!

您可以使用
记住
策略为表达式命名,生成一个可以归纳分析的变量。该策略生成一个将变量连接到记住的表达式的等式,允许您跟踪所需的信息

说明,考虑下面的证明脚本。

Record Foo : Type := mkFoo { foo: nat }.

Definition double (f: Foo) : Foo :=
  mkFoo (2 * foo f)%nat.

Theorem double_doubles: forall (f: Foo),
    foo (double f) = (2 * foo f)%nat.
Proof.
  intros.
  remember (foo f) as n eqn:E.
  revert f E.
  induction n.
调用
记住
后,目标变为:

  f : Foo
  n : nat
  E : n = foo f
  ============================
  foo (double f) = 2 * n

如果你在
记住
之后直接对
n
进行归纳,你可能无法完成你的证明,因为你得到的归纳假设不够笼统。如果你遇到这个问题,你可能需要概括定义
n
的表达式中出现的一些变量>.在上面的脚本中,调用
revert f E
f
E
放回到目标中,解决了这个问题。

注意到
double\u double
可以通过
自反性
单独解决。@的确:)但是为了说明起见,我将示例简化了。实际问题更复杂。谢谢!“还原”和“广义相关”之间有区别吗?@SiddharthBhat
revert
如果您试图还原上下文中另一个术语或假设类型中出现的内容,则会出现错误
generalizedependent
将计算所有类型依赖于广义项的术语,并将它们放回。在
revert dependent
generalizedependent
之间?@eponier问得好。我不知道。