Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Set Implicit Arguments.
Streams
CoInductive Stream (A : Type) := Cons : A -> Stream A -> Stream A. Section Streams. Variable A : Type. Notation Stream := (Stream A). Definition hd (x:Stream) := match x with | Cons a _ => a end. Definition tl (x:Stream) := match x with | Cons _ s => s end. Fixpoint Str_nth_tl (n:nat) (s:Stream) : Stream := match n with | O => s | S m => Str_nth_tl m (tl s) end. Definition Str_nth (n:nat) (s:Stream) : A := hd (Str_nth_tl n s).A:Typeforall x : Stream, x = match x with | Cons a s => Cons a s endA:Typeforall x : Stream, x = match x with | Cons a s => Cons a s endA:Typex:Streamx = match x with | Cons a s => Cons a s endtrivial. Qed.A:Typex:Streamforall (a : A) (s : Stream), Cons a s = Cons a sA:Typeforall (n : nat) (s : Stream), tl (Str_nth_tl n s) = Str_nth_tl n (tl s)simple induction n; simpl; auto. Qed. Hint Resolve tl_nth_tl: datatypes.A:Typeforall (n : nat) (s : Stream), tl (Str_nth_tl n s) = Str_nth_tl n (tl s)A:Typeforall (n m : nat) (s : Stream), Str_nth_tl n (Str_nth_tl m s) = Str_nth_tl (n + m) sA:Typen, n0:natH:forall (m0 : nat) (s0 : Stream), Str_nth_tl n0 (Str_nth_tl m0 s0) = Str_nth_tl (n0 + m0) s0m:nats:StreamStr_nth_tl n0 (tl (Str_nth_tl m s)) = Str_nth_tl (n0 + m) (tl s)rewrite tl_nth_tl; trivial with datatypes. Qed.A:Typen, n0:natH:forall (m0 : nat) (s0 : Stream), Str_nth_tl n0 (Str_nth_tl m0 s0) = Str_nth_tl (n0 + m0) s0m:nats:StreamStr_nth_tl n0 (tl (Str_nth_tl m s)) = Str_nth_tl n0 (Str_nth_tl m (tl s))intros; unfold Str_nth; rewrite Str_nth_tl_plus; trivial with datatypes. Qed.A:Typeforall (n m : nat) (s : Stream), Str_nth n (Str_nth_tl m s) = Str_nth (n + m) s
Extensional Equality between two streams
CoInductive EqSt (s1 s2: Stream) : Prop :=
eqst :
hd s1 = hd s2 -> EqSt (tl s1) (tl s2) -> EqSt s1 s2.
A coinduction principle
Ltac coinduction proof :=
cofix proof; intros; constructor;
[ clear proof | try (apply proof; clear proof) ].
Extensional equality is an equivalence relation
A:Typeforall s : Stream, EqSt s sreflexivity. Qed.A:Types:Streamhd s = hd sA:Typeforall s1 s2 : Stream, EqSt s1 s2 -> EqSt s2 s1A:Types1, s2:StreamH:EqSt s1 s2hd s2 = hd s1A:Types1, s2:StreamH:EqSt s1 s2EqSt (tl s1) (tl s2)case H; intros; symmetry ; assumption.A:Types1, s2:StreamH:EqSt s1 s2hd s2 = hd s1case H; intros; assumption. Qed.A:Types1, s2:StreamH:EqSt s1 s2EqSt (tl s1) (tl s2)A:Typeforall s1 s2 s3 : Stream, EqSt s1 s2 -> EqSt s2 s3 -> EqSt s1 s3A:Types1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3hd s1 = hd s3A:TypeEq_trans:forall s0 s4 s5 : Stream, EqSt s0 s4 -> EqSt s4 s5 -> EqSt s0 s5s1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3EqSt (tl s1) (tl s3)A:Types1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3hd s1 = hd s3A:Types1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3hd s1 = hd s2A:Types1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3hd s2 = hd s3case H; intros; assumption.A:Types1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3hd s1 = hd s2case H0; intros; assumption.A:Types1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3hd s2 = hd s3A:TypeEq_trans:forall s0 s4 s5 : Stream, EqSt s0 s4 -> EqSt s4 s5 -> EqSt s0 s5s1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3EqSt (tl s1) (tl s3)A:TypeEq_trans:forall s0 s4 s5 : Stream, EqSt s0 s4 -> EqSt s4 s5 -> EqSt s0 s5s1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3EqSt (tl s1) (tl s2)A:TypeEq_trans:forall s0 s4 s5 : Stream, EqSt s0 s4 -> EqSt s4 s5 -> EqSt s0 s5s1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3EqSt (tl s2) (tl s3)case H; trivial with datatypes.A:TypeEq_trans:forall s0 s4 s5 : Stream, EqSt s0 s4 -> EqSt s4 s5 -> EqSt s0 s5s1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3EqSt (tl s1) (tl s2)case H0; trivial with datatypes. Qed.A:TypeEq_trans:forall s0 s4 s5 : Stream, EqSt s0 s4 -> EqSt s4 s5 -> EqSt s0 s5s1, s2, s3:StreamH:EqSt s1 s2H0:EqSt s2 s3EqSt (tl s2) (tl s3)
The definition given is equivalent to require the elements at each
position to be equal
A:Typeforall (n : nat) (s1 s2 : Stream), EqSt s1 s2 -> Str_nth n s1 = Str_nth n s2A:Typen:natforall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl 0 s1) = hd (Str_nth_tl 0 s2)A:Typen:natforall n0 : nat, (forall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl n0 s1) = hd (Str_nth_tl n0 s2)) -> forall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl (S n0) s1) = hd (Str_nth_tl (S n0) s2)intros s1 s2 H; case H; trivial with datatypes.A:Typen:natforall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl 0 s1) = hd (Str_nth_tl 0 s2)A:Typen:natforall n0 : nat, (forall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl n0 s1) = hd (Str_nth_tl n0 s2)) -> forall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl (S n0) s1) = hd (Str_nth_tl (S n0) s2)A:Typen, m:nathypind:forall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl m s1) = hd (Str_nth_tl m s2)forall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl (S m) s1) = hd (Str_nth_tl (S m) s2)A:Typen, m:nathypind:forall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl m s1) = hd (Str_nth_tl m s2)forall s1 s2 : Stream, EqSt s1 s2 -> hd (Str_nth_tl m (tl s1)) = hd (Str_nth_tl m (tl s2))A:Typen, m:nathypind:forall s0 s3 : Stream, EqSt s0 s3 -> hd (Str_nth_tl m s0) = hd (Str_nth_tl m s3)s1, s2:StreamH:EqSt s1 s2hd (Str_nth_tl m (tl s1)) = hd (Str_nth_tl m (tl s2))case H; trivial with datatypes. Qed.A:Typen, m:nathypind:forall s0 s3 : Stream, EqSt s0 s3 -> hd (Str_nth_tl m s0) = hd (Str_nth_tl m s3)s1, s2:StreamH:EqSt s1 s2EqSt (tl s1) (tl s2)A:Typeforall s1 s2 : Stream, (forall n : nat, Str_nth n s1 = Str_nth n s2) -> EqSt s1 s2A:Types1, s2:StreamH:forall n : nat, Str_nth n s1 = Str_nth n s2hd s1 = hd s2A:Types1, s2:StreamH:forall n : nat, Str_nth n s1 = Str_nth n s2forall n : nat, Str_nth n (tl s1) = Str_nth n (tl s2)apply (H 0).A:Types1, s2:StreamH:forall n : nat, Str_nth n s1 = Str_nth n s2hd s1 = hd s2intros n; apply (H (S n)). Qed. Section Stream_Properties. Variable P : Stream -> Prop. (*i Inductive Exists : Stream -> Prop := | Here : forall x:Stream, P x -> Exists x | Further : forall x:Stream, ~ P x -> Exists (tl x) -> Exists x. i*) Inductive Exists ( x: Stream ) : Prop := | Here : P x -> Exists x | Further : Exists (tl x) -> Exists x. CoInductive ForAll (x: Stream) : Prop := HereAndFurther : P x -> ForAll (tl x) -> ForAll x.A:Types1, s2:StreamH:forall n : nat, Str_nth n s1 = Str_nth n s2forall n : nat, Str_nth n (tl s1) = Str_nth n (tl s2)A:TypeP:Stream -> Propforall (m : nat) (x : Stream), ForAll x -> ForAll (Str_nth_tl m x)A:TypeP:Stream -> Propforall (m : nat) (x : Stream), ForAll x -> ForAll (Str_nth_tl m x)A:TypeP:Stream -> Propforall x : Stream, ForAll x -> ForAll (Str_nth_tl 0 x)A:TypeP:Stream -> Propm:natIHm:forall x : Stream, ForAll x -> ForAll (Str_nth_tl m x)forall x : Stream, ForAll x -> ForAll (Str_nth_tl (S m) x)tauto.A:TypeP:Stream -> Propforall x : Stream, ForAll x -> ForAll (Str_nth_tl 0 x)A:TypeP:Stream -> Propm:natIHm:forall x : Stream, ForAll x -> ForAll (Str_nth_tl m x)forall x : Stream, ForAll x -> ForAll (Str_nth_tl (S m) x)A:TypeP:Stream -> Propm:natIHm:forall x0 : Stream, ForAll x0 -> ForAll (Str_nth_tl m x0)x:StreamH:ForAll (tl x)ForAll (Str_nth_tl (S m) x)A:TypeP:Stream -> Propm:natIHm:forall x0 : Stream, ForAll x0 -> ForAll (Str_nth_tl m x0)x:StreamH:ForAll (tl x)ForAll (Str_nth_tl m (tl x))assumption. Qed. Section Co_Induction_ForAll. Variable Inv : Stream -> Prop. Hypothesis InvThenP : forall x:Stream, Inv x -> P x. Hypothesis InvIsStable : forall x:Stream, Inv x -> Inv (tl x).A:TypeP:Stream -> Propm:natIHm:forall x0 : Stream, ForAll x0 -> ForAll (Str_nth_tl m x0)x:StreamH:ForAll (tl x)ForAll (tl x)coinduction ForAll_coind; auto. Qed. End Co_Induction_ForAll. End Stream_Properties. End Streams. Section Map. Variables A B : Type. Variable f : A -> B. CoFixpoint map (s:Stream A) : Stream B := Cons (f (hd s)) (map (tl s)).A:TypeP, Inv:Stream -> PropInvThenP:forall x : Stream, Inv x -> P xInvIsStable:forall x : Stream, Inv x -> Inv (tl x)forall x : Stream, Inv x -> ForAll xA, B:Typef:A -> Bforall (n : nat) (s : Stream A), Str_nth_tl n (map s) = map (Str_nth_tl n s)A, B:Typef:A -> Bforall (n : nat) (s : Stream A), Str_nth_tl n (map s) = map (Str_nth_tl n s)A, B:Typef:A -> Bforall s : Stream A, Str_nth_tl 0 (map s) = map (Str_nth_tl 0 s)A, B:Typef:A -> Bn:natIHn:forall s : Stream A, Str_nth_tl n (map s) = map (Str_nth_tl n s)forall s : Stream A, Str_nth_tl (S n) (map s) = map (Str_nth_tl (S n) s)reflexivity.A, B:Typef:A -> Bforall s : Stream A, Str_nth_tl 0 (map s) = map (Str_nth_tl 0 s)A, B:Typef:A -> Bn:natIHn:forall s : Stream A, Str_nth_tl n (map s) = map (Str_nth_tl n s)forall s : Stream A, Str_nth_tl (S n) (map s) = map (Str_nth_tl (S n) s)A, B:Typef:A -> Bn:natIHn:forall s : Stream A, Str_nth_tl n (map s) = map (Str_nth_tl n s)forall s : Stream A, Str_nth_tl n (map (tl s)) = map (Str_nth_tl n (tl s))apply IHn. Qed.A, B:Typef:A -> Bn:natIHn:forall s0 : Stream A, Str_nth_tl n (map s0) = map (Str_nth_tl n s0)s:Stream AStr_nth_tl n (map (tl s)) = map (Str_nth_tl n (tl s))A, B:Typef:A -> Bforall (n : nat) (s : Stream A), Str_nth n (map s) = f (Str_nth n s)A, B:Typef:A -> Bforall (n : nat) (s : Stream A), Str_nth n (map s) = f (Str_nth n s)A, B:Typef:A -> Bn:nats:Stream AStr_nth n (map s) = f (Str_nth n s)A, B:Typef:A -> Bn:nats:Stream Ahd (Str_nth_tl n (map s)) = f (hd (Str_nth_tl n s))reflexivity. Qed.A, B:Typef:A -> Bn:nats:Stream Ahd (map (Str_nth_tl n s)) = f (hd (Str_nth_tl n s))A, B:Typef:A -> Bforall (P : Stream B -> Prop) (S : Stream A), ForAll (fun s : Stream A => P (map s)) S <-> ForAll P (map S)A, B:Typef:A -> Bforall (P : Stream B -> Prop) (S : Stream A), ForAll (fun s : Stream A => P (map s)) S <-> ForAll P (map S)split; generalize S; clear S; cofix ForAll_map; intros S; constructor; destruct H as [H0 H]; firstorder. Qed.A, B:Typef:A -> BP:Stream B -> PropS:Stream AForAll (fun s : Stream A => P (map s)) S <-> ForAll P (map S)A, B:Typef:A -> Bforall (P : Stream B -> Prop) (S : Stream A), Exists (fun s : Stream A => P (map s)) S -> Exists P (map S)A, B:Typef:A -> Bforall (P : Stream B -> Prop) (S : Stream A), Exists (fun s : Stream A => P (map s)) S -> Exists P (map S)(induction H;[left|right]); firstorder. Defined. End Map. Section Constant_Stream. Variable A : Type. Variable a : A. CoFixpoint const : Stream A := Cons a const. End Constant_Stream. Section Zip. Variable A B C : Type. Variable f: A -> B -> C. CoFixpoint zipWith (a:Stream A) (b:Stream B) : Stream C := Cons (f (hd a) (hd b)) (zipWith (tl a) (tl b)).A, B:Typef:A -> BP:Stream B -> PropS:Stream AH:Exists (fun s : Stream A => P (map s)) SExists P (map S)A, B, C:Typef:A -> B -> Cforall (n : nat) (a : Stream A) (b : Stream B), Str_nth_tl n (zipWith a b) = zipWith (Str_nth_tl n a) (Str_nth_tl n b)A, B, C:Typef:A -> B -> Cforall (n : nat) (a : Stream A) (b : Stream B), Str_nth_tl n (zipWith a b) = zipWith (Str_nth_tl n a) (Str_nth_tl n b)A, B, C:Typef:A -> B -> Cforall (a : Stream A) (b : Stream B), Str_nth_tl 0 (zipWith a b) = zipWith (Str_nth_tl 0 a) (Str_nth_tl 0 b)A, B, C:Typef:A -> B -> Cn:natIHn:forall (a : Stream A) (b : Stream B), Str_nth_tl n (zipWith a b) = zipWith (Str_nth_tl n a) (Str_nth_tl n b)forall (a : Stream A) (b : Stream B), Str_nth_tl (S n) (zipWith a b) = zipWith (Str_nth_tl (S n) a) (Str_nth_tl (S n) b)reflexivity.A, B, C:Typef:A -> B -> Cforall (a : Stream A) (b : Stream B), Str_nth_tl 0 (zipWith a b) = zipWith (Str_nth_tl 0 a) (Str_nth_tl 0 b)A, B, C:Typef:A -> B -> Cn:natIHn:forall (a : Stream A) (b : Stream B), Str_nth_tl n (zipWith a b) = zipWith (Str_nth_tl n a) (Str_nth_tl n b)forall (a : Stream A) (b : Stream B), Str_nth_tl (S n) (zipWith a b) = zipWith (Str_nth_tl (S n) a) (Str_nth_tl (S n) b)A, B, C:Typef:A -> B -> Cn:natIHn:forall (a : Stream A) (b : Stream B), Str_nth_tl n (zipWith a b) = zipWith (Str_nth_tl n a) (Str_nth_tl n b)x:Axs:Stream Ay:Bys:Stream BStr_nth_tl (S n) (zipWith (Cons x xs) (Cons y ys)) = zipWith (Str_nth_tl (S n) (Cons x xs)) (Str_nth_tl (S n) (Cons y ys))A, B, C:Typef:A -> B -> Cn:natIHn:forall (a : Stream A) (b : Stream B), Str_nth_tl n (zipWith a b) = zipWith (Str_nth_tl n a) (Str_nth_tl n b)x:Axs:Stream Ay:Bys:Stream BStr_nth_tl (S n) (zipWith (Cons x xs) (Cons y ys)) = zipWith (Str_nth_tl (S n) (Cons x xs)) (Str_nth_tl (S n) (Cons y ys))apply IHn. Qed.A, B, C:Typef:A -> B -> Cn:natIHn:forall (a : Stream A) (b : Stream B), Str_nth_tl n (zipWith a b) = zipWith (Str_nth_tl n a) (Str_nth_tl n b)x:Axs:Stream Ay:Bys:Stream BStr_nth_tl n (zipWith xs ys) = zipWith (Str_nth_tl n xs) (Str_nth_tl n ys)A, B, C:Typef:A -> B -> Cforall (n : nat) (a : Stream A) (b : Stream B), Str_nth n (zipWith a b) = f (Str_nth n a) (Str_nth n b)A, B, C:Typef:A -> B -> Cforall (n : nat) (a : Stream A) (b : Stream B), Str_nth n (zipWith a b) = f (Str_nth n a) (Str_nth n b)A, B, C:Typef:A -> B -> Cn:nata:Stream Ab:Stream BStr_nth n (zipWith a b) = f (Str_nth n a) (Str_nth n b)A, B, C:Typef:A -> B -> Cn:nata:Stream Ab:Stream Bhd (Str_nth_tl n (zipWith a b)) = f (hd (Str_nth_tl n a)) (hd (Str_nth_tl n b))reflexivity. Qed. End Zip. Unset Implicit Arguments.A, B, C:Typef:A -> B -> Cn:nata:Stream Ab:Stream Bhd (zipWith (Str_nth_tl n a) (Str_nth_tl n b)) = f (hd (Str_nth_tl n a)) (hd (Str_nth_tl n b))