Ltac致电" cofix"失败。错误:所有方法都必须以共感类型构建元素

时间:2017-06-18 04:04:10

标签: 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)) (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.

输出:

Ltac call to "cofix" failed.
Error: All methods must construct elements in coinductive types.

我不确定这意味着什么 - mapinterleave都是简单的corecursive函数,它们构建了coinductive类型的值。问题是什么?

1 个答案:

答案 0 :(得分:2)

问题源于这样一个事实:=表示eq表示map f (interleave (s1, s2)),这是一种归纳类型,不是一个共同表达。

相反,您可以显示流interleave (map f s1, map f s2)s1在扩展方面相同。以下是Coq参考手册(§1.3.3

的摘录
  

为了证明两个流s2EqSt s1 s2的扩展相等,我们必须构造一个无限的相等证明,即eq类型的无限对象。

EqSt更改为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. 后,我们可以证明这个问题:

activ

顺便说一下,在this CPDT章节中可以找到许多处理共同数据类型的技巧。