(* Coq'Art CH 13 *) (* CH 13.1 *) Set Implicit Arguments. CoInductive LList (A:Set) : Set := LNil : LList A | LCons : A -> LList A -> LList A. Implicit Arguments LNil [A]. (* CH 13.2 *) Fixpoint LNth (A:Set) (n:nat) (l:LList A){struct n} : option A := match l with LNil => None | LCons a l' => match n with O => Some a | S p => LNth p l' end end. (* CH 13.3 *) CoFixpoint from (n:nat) : LList nat := LCons n (from (S n)). CoFixpoint repeat (A:Set)(a:A) : LList A := LCons a (repeat a). CoFixpoint LAppend (A:Set) (u v: LList A) : LList A := match u with LNil => v | LCons a u' => LCons a (LAppend u' v) end. CoFixpoint general_omega (A:Set) (u v:LList A) : LList A := match v with LNil => u | LCons b v' => match u with LNil => LCons b (general_omega v' v) | LCons a u' => LCons a (general_omega u' v) end end. Definition omega (A:Set) (u:LList A) : LList A := general_omega u u. (* CH 13.4 *) Definition LList_decompose (A:Set) (l:LList A) : LList A := match l with LNil => LNil | LCons a l' => LCons a l' end. Theorem LList_decomposition_lemma: forall (A:Set) (l:LList A), l = LList_decompose l. Proof. intro a. intro l. case l. simpl. reflexivity. intro b. intro l'. simpl. reflexivity. Qed. Ltac LList_unfold term := apply trans_equal with (1 := LList_decomposition_lemma term). Theorem LAppend_LNil : forall (A:Set) (v:LList A), LAppend LNil v = v. Proof. intro A. intro v. LList_unfold (LAppend LNil v). case v. simpl. reflexivity. intro a. intro l. simpl. reflexivity. Qed. Theorem LAppend_LCons : forall (A:Set) (a:A) (u v:LList A), LAppend (LCons a u) v = LCons a (LAppend u v). Proof. intros A a u v. LList_unfold (LAppend (LCons a u) v). case v. simpl. reflexivity. intros a0 l. simpl. reflexivity. Qed. Hint Resolve LAppend_LNil LAppend_LCons : llists. Hint Rewrite LAppend_LNil LAppend_LCons : llists. (* CH 13.5 *) Inductive Finite (A:Set) : LList A -> Prop := Finite_LNil : Finite LNil | Finite_LCons : forall (a:A) (l:LList A), Finite l -> Finite (LCons a l). Hint Rewrite Finite_LNil Finite_LCons : llists. Hint Resolve Finite_LNil Finite_LCons : llists. Theorem Finite_of_LCons : forall (A:Set) (a:A) (l:LList A), Finite (LCons a l) -> Finite l. Proof. intros A a l x. inversion x. exact H0. Qed. Lemma from_unfold: forall n:nat, from n = LCons n (from (S n)). Proof. intro n. LList_unfold (from n). simpl. reflexivity. Qed. (* CH 13.6 CO-INDUCTIVE PREDICATES *) CoInductive Infinite (A:Set) : LList A -> Prop := Infinite_LCons : forall (a:A) (l:LList A), Infinite l -> Infinite (LCons a l). Hint Rewrite Infinite_LCons : llists. Hint Resolve Infinite_LCons : llists. Definition F_from : (forall n:nat, Infinite (from n)) -> forall n:nat, Infinite (from n). intro H. intro n. rewrite (from_unfold n). split. apply H. Defined. Theorem from_Infinite_V0 : forall n:nat, Infinite (from n). Proof cofix H : forall n:nat, Infinite (from n) := F_from H. Theorem from_Infinite_V1 : forall n:nat, Infinite (from n). Proof. cofix H. apply (F_from H). Qed. Theorem from_Infinite : forall n:nat, Infinite (from n). Proof. cofix H. (* apply H. *) (* Guarded. *) intro n. rewrite (from_unfold n). apply Infinite_LCons. apply H. Qed. Theorem LNil_not_Infinite : forall A:Set, ~Infinite (LNil (A:=A)). Proof. intro A. unfold not. intro H. inversion H. Qed. (* ex 13.12 *) Lemma repeat_unfold: forall A:Set, forall a:A, repeat a = LCons a (repeat a). Proof. intro A. intro a. LList_unfold (repeat a). simpl. reflexivity. Qed. Lemma repeat_infinite : forall (A:Set) (a:A), Infinite (repeat a). Proof. intro A. cofix a. intro b. rewrite (repeat_unfold b). apply Infinite_LCons. apply a. Qed. (* ex 13.15 *) Theorem Infinite_of_LCons : forall (A:Set ) (a:A) (u:LList A), Infinite (LCons a u) -> Infinite u. Proof. intros A a u x. inversion x. exact H0. Qed. Lemma LAppend_of_Infinite : forall (A:Set) (u:LList A), Infinite u -> forall (v:LList A), Infinite (LAppend u v). Proof. intros A. cofix H. intros u. case u. intro H0. inversion H0. intros a l H0 v. autorewrite with llists using auto with llists. split. apply H. inversion H0. exact H2. Qed. Lemma Finite_not_Infinite : forall (A:Set) (l:LList A), Finite l -> ~Infinite l. Proof. intros A l H. elim H. unfold not. intro H0. inversion H0. unfold not. intros a l0 H0 H1 H2. inversion H2. apply H1. exact H4. Qed. Lemma Infinite_not_Finite : forall (A:Set) (l:LList A), Infinite l -> ~Finite l. Proof. unfold not. intros A l H H0. absurd (Infinite l). apply Finite_not_Infinite. exact H0. exact H. Qed. Lemma Not_Finite_Infinite : forall (A:Set) (l:LList A), ~Finite l -> Infinite l. unfold not. cofix H. intros A l. case l. intro H0. absurd (Finite (LNil (A := A))). exact H0. apply Finite_LNil. intros a l0 H0. apply Infinite_LCons. apply H. intro H1. apply H0. apply Finite_LCons. exact H1. Qed. (* H13.7 BISIMILARITY*) CoInductive bisimilar (A:Set) : LList A -> LList A -> Prop := bisim_LNil : bisimilar LNil LNil | bisim_LCons : forall (a:A) (l l':LList A), bisimilar l l' -> bisimilar (LCons a l) (LCons a l'). Hint Rewrite bisim_LNil bisim_LCons : llists. Hint Resolve bisim_LNil bisim_LCons : llists. (* ex 13.9 *) Require Import Relations. Check reflexive. Lemma bisimilar_refl : forall (A:Set), reflexive (LList A) (bisimilar (A:=A)). Proof. intro A. unfold reflexive. cofix H. intro u. case u. apply bisim_LNil. intros a l. apply bisim_LCons. apply H. Qed. Hint Resolve bisimilar_refl: llists. Lemma bisimilar_sym : forall (A:Set), symmetric (LList A) (bisimilar (A:=A)). unfold symmetric. intro A. cofix H. destruct x; destruct y. auto with llists. intro H0. inversion H0. intro H0. inversion H0. intro H0. inversion H0. apply bisim_LCons. auto. Qed. Lemma bisimilar_trans : forall (A:Set), transitive (LList A) (bisimilar (A:=A)). Proof. unfold transitive. intro A. cofix H. intros x. case x. intros y. case y. auto. intros a l w H0. inversion H0. destruct y. intros z H0. inversion H0. intros z. intro H0. intro H1. inversion_clear H1. inversion_clear H0. apply bisim_LCons. eapply H. eauto. exact H2. Qed. Theorem bisimilar_equiv : forall (A:Set), equiv (LList A) (bisimilar (A:=A)). Proof. split. apply bisimilar_refl. split. apply bisimilar_trans. apply bisimilar_sym. Qed. (* ex13.21 *) Theorem bisimilar_of_Finite_is_Finite : forall (A:Set) (l:LList A), Finite l -> forall (l':LList A), bisimilar l l' -> Finite l'. Proof. intros A l H. elim H. intro l'. case l'. intro H0. apply Finite_LNil. intros a l0 H0. inversion H0. intros a l0 H0 H1 l'. case l'. intro H2. inversion H2. intros a0 l1 H2. inversion H2. apply Finite_LCons. apply H1. exact H4. Qed. Theorem bisimilar_of_Infinite_is_Infinite : forall (A:Set) (l:LList A), Infinite l -> forall (l':LList A), bisimilar l l' -> Infinite l'. Proof. intros A. cofix H. intro l. case l. intro H0. inversion H0. intros a l0 H0 l'. case l'. intro H1. inversion H1. intros a0 l1 H1. apply Infinite_LCons. apply H with l0. apply Infinite_of_LCons with a. exact H0. inversion H1. exact H3. Qed. (* ex 13.22 *) Theorem bisimilar_of_Finite_is_eq : forall (A:Set) (l:LList A), Finite l -> forall (l':LList A), bisimilar l l' -> l = l'. Proof. intros A l H. elim H. intros l' H0. inversion H0. reflexivity. intros a l0 H0 H1 l'. case l'. intro H2. inversion H2. intros a0 l1 H2. inversion H2. rewrite (H1 l1). reflexivity. exact H4. Qed. Theorem LAppend_assoc : forall (A:Set)(u v w:LList A), bisimilar (LAppend u (LAppend v w)) (LAppend (LAppend u v) w). Proof. intro A. cofix H. intros u. case u. intros v w. autorewrite with llists. apply bisimilar_refl. intros a l v w. autorewrite with llists. auto with llists. Qed.