Proving equality on coinductive lazy lists in Coq

南笙酒味 提交于 2019-12-06 08:40:12

A simple rule is to use cofix as soon as possible in your proofs.

Actually, in your proof of LAppend_v_LNil, the guarded condition is already violated at destruct v. You can check this fact using the command Guarded, which helps testing before the end of the proof if all the uses of coinduction hypotheses are legit.

Lemma LAppend_v_LNil : forall (A:Set) (v:LList A), LListEq  (LAppend v LNil)  v.
  intros.
  cofix.
  destruct v. Fail Guarded.
Abort.

You should actually swap intros and cofix. From there, the proof is not difficult.

EDIT: here is the complete solution.

Lemma LAppend_v_LNil : forall (A:Set) (v:LList A), LListEq (LAppend v LNil)  v.
  cofix.
  intros.
  destruct v. Guarded. (* now we can safely destruct v *)
  - rewrite LAppend_LNil.
    constructor.
  - rewrite (LList_decompose (LAppend _ _)).
    simpl. constructor. apply LAppend_v_LNil.
Qed.

You guessed it right: just like for functions, Coq's generic notion of equality is too weak to be useful for most coinductive types. If you want to prove your result, you need to replace eq by a coinductive notion of equality for lists; for instance:

CoInductive LListEq (A:Set) : LList A -> LList A -> Prop :=
| LNilEq : LListEq A LNil LNil
| LConsEq x lst1 lst2 : LListEq A lst1 lst2 -> 
  LListEq A (LCons x lst1) (LCons x lst2).

Manipulating infinite objects is a vast topic in Coq. If you want to learn more, Adam Chlipala's CPDT has an entire chapter on coinduction.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!