(** printing \2/ $\cup$ #&cup;# *)
(** printing <2= $\subseteq$ #&sube;# *)
(** printing forall $\forall$ #&forall;# *)
(** printing -> $\rightarrow$ #&rarr;# *)
(** printing /\ $\land$ #&and;# *)
Set Implicit Arguments.
Set Contextual Implicit.
(** * A Mixed Induction-Coinduction Example  Written by Steve Zdancewic. *)
CoInductive stream (A:Type) :=
| snil : stream A
| scons : A -> stream A -> stream A
.
Arguments scons {_} _ _.
Definition id_match_stream {A} (s:stream A) : stream A :=
match s with
| snil => snil
| scons x t => scons x t
end.
(* A more relaxed notion of equivalence where the 0's can be inserted finitely often in either stream. *)
Inductive seq_step (seq : stream nat -> stream nat -> Prop) : stream nat -> stream nat -> Prop :=
| seq_nil  : seq_step seq snil snil
| seq_cons : forall s1 s2 n (R : seq s1 s2), seq_step seq (scons n s1) (scons n s2)
| seq_cons_z_l : forall s1 s2, seq_step seq s1 s2 -> seq_step seq (scons 0 s1) s2
| seq_cons_z_r : forall s1 s2, seq_step seq s1 s2 -> seq_step seq s1 (scons 0 s2)
.
Hint Constructors seq_step : core.
Hint Resolve seq_step_mono : paco.
Definition seq (s t : stream nat) := paco2 seq_step bot2 s t .
Hint Unfold seq : core.

Lemma seq_step_refl : forall (R:stream nat -> stream nat -> Prop),
(forall d, R d d) -> forall d, seq_step R d d.