Coq 陆路交通谘询委员会呼吁「;cofix“;失败。错误:所有方法都必须以共导类型构造元素

Coq 陆路交通谘询委员会呼吁「;cofix“;失败。错误:所有方法都必须以共导类型构造元素,coq,coq-tactic,coinduction,Coq,Coq Tactic,Coinduction,输出: Require Import Streams. CoFixpoint map {X Y : Type} (f : X -> Y) (s : Stream X) : Stream Y := Cons (f (hd s)) (map f (tl s)). CoFixpoint interleave {X : Type} (s : Stream X * Stream X) : Stream X := Cons (hd (fst s)) (Cons (hd (snd s)) (in

输出:

Require Import Streams.

CoFixpoint map {X Y : Type} (f : X -> Y) (s : Stream X) : Stream Y :=
  Cons (f (hd s)) (map f (tl s)).

CoFixpoint interleave {X : Type} (s : Stream X * Stream X) : Stream X := Cons (hd (fst s)) (Cons (hd (snd s)) (interleave (tl (fst s), tl (snd s)))).

Lemma map_interleave : forall {X Y : Type} (f : X -> Y) (s1 s2 : Stream X), map f (interleave (s1, s2)) = interleave (map f s1, map f s2).
Proof.
  Fail cofix. (* error *)
Abort.

我不确定这意味着什么-无论是
map
还是
interleave
都是直接的协同草书函数,用于构建共归纳类型的值。问题是什么?

问题源于这样一个事实,即
=
符号代表
eq
,它是一种归纳类型,而不是共导类型

相反,您可以显示流
map f(interleave(s1,s2))
interleave(map fs1,map fs2)
在扩展上是相等的。以下是Coq参考手册的摘录()

为了证明两个流
s1
s2
的广义相等,我们必须构造一个无限相等的证明,即,一个类型为
EqSt s1 s2
的无限对象

eq
更改为
EqSt
后,我们可以证明引理:

Ltac call to "cofix" failed.
Error: All methods must construct elements in coinductive types.
顺便说一下,在CPDT一章中可以找到许多处理共导数据类型的技巧。

这是一个简单的例子。
Lemma map_interleave : forall {X Y : Type} (f : X -> Y) (s1 s2 : Stream X),
  EqSt (map f (interleave (s1, s2))) (interleave (map f s1, map f s2)).
Proof.
  cofix.
  intros X Y f s1 s2.
  do 2 (apply eqst; [reflexivity |]).
  case s1 as [h1 s1], s2 as [h2 s2].
  change (tl (tl (map f (interleave (Cons h1 s1, Cons h2 s2))))) with
         (map f (interleave (s1, s2))).
  change (tl (tl (interleave (map f (Cons h1 s1), map f (Cons h2 s2))))) with
         (interleave (map f s1, map f s2)).
  apply map_interleave.
Qed.