72 lines
1.6 KiB
Coq
72 lines
1.6 KiB
Coq
CoInductive stream (A : Type) : Type :=
|
|
| scons : A -> stream A -> stream A.
|
|
Arguments scons {A}.
|
|
|
|
CoFixpoint map {A B : Type} (f:A->B) (s : stream A): stream B :=
|
|
match s with
|
|
| scons x xs => scons (f x) (map f xs)
|
|
end.
|
|
|
|
CoFixpoint interleave {A:Type} (s1 s2:stream A) : stream A :=
|
|
match s1, s2 with
|
|
| scons x xs, scons y ys => scons x (scons y (interleave xs ys))
|
|
end.
|
|
|
|
Fixpoint take {A:Type} (n:nat) (s:stream A) : list A :=
|
|
match n, s with
|
|
| O, _ => nil
|
|
| S n', scons x xs => cons x (take n' xs)
|
|
end.
|
|
|
|
(* Every corecursive call must be guarded by a constructor *)
|
|
|
|
CoFixpoint true_falses : stream bool := scons true (false_trues)
|
|
with false_trues : stream bool := scons false (true_falses).
|
|
|
|
Definition tl {A:Type} (s:stream A) : stream A :=
|
|
match s with
|
|
| scons _ xs => xs
|
|
end.
|
|
|
|
CoFixpoint zeros : stream nat := scons 0 zeros.
|
|
CoFixpoint ones : stream nat := scons 1 ones.
|
|
CoFixpoint ones' : stream nat := map S zeros.
|
|
|
|
Theorem ones_eq : ones = ones'.
|
|
Proof.
|
|
(* Unprovable goal *)
|
|
Abort.
|
|
|
|
CoInductive stream_eq {A:Type} : stream A -> stream A -> Prop :=
|
|
| Stream_eq : forall (x:A) (t1 t2:stream A),
|
|
stream_eq t1 t2 -> stream_eq (scons x t1) (scons x t2).
|
|
|
|
Theorem ones_eq : stream_eq ones ones'.
|
|
Proof.
|
|
cofix ones_eq.
|
|
assumption.
|
|
Abort.
|
|
|
|
Definition strid {A:Type} (s:stream A) : stream A :=
|
|
match s with
|
|
| scons x xs => scons x xs
|
|
end.
|
|
|
|
Theorem strid_eq {A:Type}: forall (s:stream A),
|
|
s = strid s.
|
|
Proof.
|
|
intros.
|
|
destruct s.
|
|
- reflexivity.
|
|
Qed.
|
|
|
|
Theorem ones_eq : stream_eq ones ones'.
|
|
Proof.
|
|
cofix ones_eq.
|
|
rewrite (strid_eq ones).
|
|
rewrite (strid_eq ones').
|
|
simpl.
|
|
constructor.
|
|
unfold map.
|
|
assumption.
|