Coq 非形式A->;A.

Coq 非形式A->;A.,coq,coinduction,Coq,Coinduction,在Coq中,共归纳的形式是证明A->A主题受保护性约束,以确保有进展。这个公式很容易出错,因为它看起来像是您在开始时就到达了目的地,并且根据证明中的当前状态,不容易看到安全性。是否有更接近归纳法的替代公式,你必须得出不同于前提的结论 例如: CoInductive stream A : Type := | SCons : A -> stream A -> stream A . Arguments SCons [A] _ _. CoInductive sEq A : stream A

在Coq中,共归纳的形式是证明A->A主题受保护性约束,以确保有进展。这个公式很容易出错,因为它看起来像是您在开始时就到达了目的地,并且根据证明中的当前状态,不容易看到安全性。是否有更接近归纳法的替代公式,你必须得出不同于前提的结论

例如:

CoInductive stream A : Type :=
| SCons : A -> stream A -> stream A
.
Arguments SCons [A] _ _.

CoInductive sEq A : stream A -> stream A -> Prop :=
| StreamEq x s0 s1 : sEq A s0 s1 -> sEq A (SCons x s0) (SCons x s1)
.
Arguments sEq [A].
Arguments StreamEq [A].

Theorem sEq_refl {A} (s : stream A) : sEq s s.
  revert s; cofix f; intros.
  destruct s.
  apply StreamEq.
  apply f.
Qed.
在cofix之后,你会得到一种奇怪的状态:

  A : Type
  f : forall s : stream A, sEq s s
  s : stream A
  ============================
  sEq s s
更糟糕的是,如果您尝试
apply f
,它将检测不到错误,直到您使用Qed关闭它

因此,基本上,有没有共同推导的公式可以在早期捕捉到这个错误,而不是等待整个证明完成并检查其可靠性?

使用。它提供了一个最大的不动点操作符来定义共导谓词,这符合合理的推理原则,因此目标看起来不像
a->a
。该库附带了一个教程()


只是一个问题:您可以使用
防护。
检查防护条件是否在证明中保持到该点。由于性能原因,它不会自动执行此操作。太棒了!总而言之,您可以将共引式包装在一个关系中,这样就可以区分顶级关系和远离它的共引式步骤。这样,你就知道什么时候,如果你真的解决了它。
From Paco Require Import paco.

Set Implicit Arguments.

CoInductive stream A : Type := SCons
  { head : A;
    tail : stream A
  }.
Arguments SCons [A] _ _.

Definition seq_ {A} (r : stream A -> stream A -> Prop) (s1 s2 : stream A) : Prop
  := head s1 = head s2 /\ r (tail s1) (tail s2).

Definition seq {A} : stream A -> stream A -> Prop := paco2 (seq_ (A := A)) bot2.

Theorem seq_refl {A} (s : stream A) : seq s s.
Proof.
  revert s; pcofix self; intros.
  pfold.
  split.
  - reflexivity.
  - right. apply self.
Qed.