From Coq Require Import Streams.
From Velus Require Import Common.
From Velus Require Import Lustre.Denot.Cpo.
General facts about Denotational streams
Lemma eq_EqSt:
forall {
A},
inclusion (
Stream A)
eq (@
EqSt A).
Proof.
intros ? xs xs' E.
now rewrite E.
Qed.
Tactic Notation "remember_st" constr(
s)
"as" ident(
x) :=
let Hx :=
fresh "H"x in
remember s as x eqn:
Hx;
apply symmetry,
eq_EqSt in Hx.
Tactic Notation "remember_ds" uconstr(
s)
"as" ident(
x) :=
let Hx :=
fresh "H"x in
remember s as x eqn:
Hx;
apply Oeq_refl_eq in Hx.
Ltac revert_all :=
repeat match goal with
|
H:_ |- _ =>
revert H
end.
Conversion to/from Coq Streams
Section Stream_DS.
we can build a Stream from a DS if it is always productive,
i.e. it is not bot at some point.
Context {
A B :
Type}.
Variable f :
A ->
B.
Definition S_of_DS (
s :
DS A) :
infinite s ->
Stream B.
revert s.
cofix Cof;
intros *
Hinf.
inversion Hinf as [
Hc Hi ].
specialize (
Cof (
rem s)
Hi).
apply uncons in Hc as [
v].
exact (
Streams.Cons (
f v)
Cof).
Defined.
Lemma _S_of_DS_eq :
forall (
s :
DS A) (
Hs :
infinite s)
t (
Ht :
infinite t),
s ==
t ->
S_of_DS s Hs ≡ S_of_DS t Ht.
Proof.
Lemma __S_of_DS_eq :
forall (
s :
DS A)
Hs t (
Heq :
s ==
t),
S_of_DS s Hs ≡ S_of_DS t ((
proj1 (
infinite_morph Heq)
Hs)).
Proof.
Lemma S_of_DS_eq :
forall (
s :
DS A)
Hs t (
Heq :
s ==
t),
exists Ht,
S_of_DS s Hs ≡ S_of_DS t Ht.
Proof.
Lemma S_of_DS_Cons :
forall xs xsi x t,
S_of_DS xs xsi ≡ Streams.Cons x t ->
exists x' xs',
xs ==
cons x' xs'
/\
f x' =
x
/\
exists H,
S_of_DS xs' H ≡ t.
Proof.
intros *
Heq.
apply infinite_decomp in xsi as H.
destruct H as (
x' &
xs' &
Hxs &
Hinf).
destruct (
S_of_DS_eq _
xsi _
Hxs)
as [
inf' Heq2].
exists x',
xs'.
split;
auto.
rewrite Heq2 in Heq.
clear -
Heq.
setoid_rewrite unfold_Stream in Heq.
simpl in Heq.
destruct inf', (
uncons i)
as (?&?&
Hdec).
apply decompCon_eq in Hdec.
inversion Hdec.
subst.
inversion Heq as [?
H];
simpl in *.
edestruct (
S_of_DS_eq _
inf')
as [
inf'' Heq3].
{
rewrite rem_cons.
reflexivity. }
rewrite Heq3 in H.
split;
eauto.
Qed.
Lemma S_of_DS_cons :
forall u U Inf,
S_of_DS (
Cpo_streams_type.cons u U)
Inf
≡ f u ⋅ (
S_of_DS U (
cons_infinite _ _ _
Inf)).
Proof.
Lemma const_DS_const :
forall v Hi,
const (
f v)
≡ S_of_DS (
DS_const v)
Hi.
Proof.
intros.
remember_st (
const (
f v))
as sl.
remember_st (
S_of_DS (
DS_const v)
Hi)
as sr.
revert_all.
cofix Cof;
intros.
destruct sl,
sr.
apply S_of_DS_Cons in Hsr as (
x &
tx &
Hxs &
Hxvx &
itx &
Eqx).
rewrite DS_const_eq in Hxs.
apply Con_eq_simpl in Hxs as [?
Heq].
inversion Hsl;
simpl in *.
constructor;
simpl;
subst;
auto.
eapply Cof;
eauto.
now rewrite <-
Eqx, (
ex_proj2 (
S_of_DS_eq _ _ _ (
symmetry Heq))).
Qed.
The other way is simpler
CoFixpoint DS_of_S (
s :
Stream A) :
DS A :=
match s with
|
Streams.Cons a s =>
CONS a (
DS_of_S s)
end.
Global Add Parametric Morphism :
DS_of_S
with signature @
EqSt A ==> @
Oeq (
DS A)
as DS_of_S_morph.
Proof.
clear;
intros.
apply DS_bisimulation_allin1
with (
R :=
fun U V =>
exists x y,
x ≡ y
/\
U ==
DS_of_S x
/\
V ==
DS_of_S y).
3:
eauto 5.
{
clear.
intros * (
x &
y &
Hxy &
Hu &
Hv)
Eq1 Eq2.
exists x,
y.
eauto. }
clear.
intros U V Hc ([] & [] &
Hxy &
Hu &
Hv).
rewrite DS_inv in Hu,
Hv;
simpl in *.
setoid_rewrite Hu.
setoid_rewrite Hv.
inv Hxy;
simpl in *;
subst.
rewrite 2
first_cons, 2
rem_cons.
split;
auto;
eauto.
Qed.
Lemma DS_of_S_const :
forall (
c :
A),
DS_of_S (
Streams.const c) ==
DS_const c.
Proof.
Lemma DS_of_S_inf :
forall s,
infinite (
DS_of_S s).
cofix Cof.
destruct s;
constructor.
-
rewrite DS_inv;
simpl;
auto.
-
rewrite (
DS_inv (
DS_of_S (
a ⋅ s)));
simpl.
rewrite rem_cons;
apply Cof.
Qed.
End Stream_DS.
Lemma DS_of_S_of_DS :
forall A (
s :
DS A)
H,
DS_of_S (
S_of_DS id s H) ==
s.
Proof.
Expressing safety properties
Section DS_Forall.
Context {
A :
Type}.
Variable P :
A ->
Prop.
CoInductive DSForall :
DS A ->
Prop :=
|
Forall_Eps :
forall s,
DSForall s ->
DSForall (
Eps s)
|
Forall_Con :
forall x s,
P x ->
DSForall s ->
DSForall (
Con x s).
Lemma DSForall_pred :
forall s,
DSForall s ->
DSForall (
pred s).
Proof.
intros s Hf.
destruct s; simpl; inversion Hf; auto.
Qed.
Lemma DSForall_tl :
forall x s,
DSForall (
Con x s) ->
DSForall s.
Proof.
now inversion 1.
Qed.
Lemma DSForall_Con_hd :
forall s x xs,
DSForall s ->
s ==
Con x xs ->
P x.
Proof.
intros *
Hf Heq.
assert (
isCon s)
as Hcon by (
rewrite Heq;
auto).
induction Hcon;
inversion Hf;
subst.
-
rewrite <-
eqEps in Heq.
apply IHHcon;
auto.
-
apply Con_hd_simpl in Heq.
now subst.
Qed.
Lemma DSForall_Oeq :
forall x y,
x ==
y ->
DSForall x ->
DSForall y.
Proof.
cofix Cof.
intros x y Heq Hf.
destruct y;
constructor.
-
rewrite <-
eqEps in Heq.
exact (
Cof _ _
Heq Hf).
-
exact (
DSForall_Con_hd _ _ _
Hf Heq).
-
apply decomp_eq in Heq as (
t & (
k &
Hp) &
Ht).
apply (
Cof t);
auto.
clear -
Hp Hf.
generalize dependent x.
induction k;
simpl;
intros;
subst.
+
inversion Hf;
auto.
+
apply (
IHk (
pred x));
auto using DSForall_pred.
Qed.
Global Add Parametric Morphism : (
DSForall)
with signature (@
Oeq (
DS A)) ==>
iff as DSForall_Oeq_mor.
Proof.
split; [|
symmetry in H];
apply DSForall_Oeq;
assumption.
Qed.
Lemma DSForall_le :
forall x y,
x <=
y ->
DSForall y ->
DSForall x.
Proof.
cofix Cof;
destruct x;
intros ?
Le Hf;
constructor;
inversion Le as [|????
HH];
eauto 2.
all:
apply decomp_eqCon in HH;
rewrite HH in *;
inv Hf;
eauto 2.
Qed.
Lemma DSForall_bot :
DSForall (
DS_bot A).
Proof.
cofix Cof.
rewrite DS_bot_eq.
constructor;
apply Cof.
Qed.
Lemma DSForall_const :
forall c,
P c ->
DSForall (
DS_const c).
Proof.
cofix Cof;
intros.
rewrite DS_inv;
simpl.
constructor;
auto.
Qed.
Lemma DSForall_all :
(
forall x,
P x) ->
forall xs,
DSForall xs.
Proof.
cofix Cof; intros; destruct xs; constructor; eauto.
Qed.
Lemma DSForall_eps :
forall s,
DSForall (
Eps s) ->
DSForall s.
inversion 1;
assumption.
Defined.
Lemma DSForall_rem :
forall s,
DSForall s ->
DSForall (
rem s).
Proof.
unfold rem,
Rem,
DSCase;
simpl.
cofix Cof;
intros.
destruct s;
inv H;
rewrite DScase_inv;
auto.
constructor;
auto.
Qed.
Lemma DSForall_nrem :
forall s n,
DSForall s ->
DSForall (
nrem n s).
Proof.
Lemma DSForall_ind :
(
forall s,
DSForall (
rem s) ->
DSForall s) ->
forall s,
DSForall s.
Abort.
Lemma DSForall_ind :
(
forall s,
DSForall (
first s) ->
DSForall (
first (
rem s))) ->
forall s,
DSForall (
first s) ->
DSForall s.
Proof.
intro Hfr.
cofix Cof.
intros s Hh.
destruct s;
constructor.
-
rewrite DS_inv in Hh.
simpl in Hh.
apply DSForall_eps in Hh.
apply Cof,
Hh.
-
rewrite DS_inv in Hh.
simpl in Hh.
now inversion Hh.
-
specialize (
Hfr (
Con a s)
Hh).
setoid_rewrite DS_inv in Hfr at 2.
simpl in Hfr.
rewrite <-
DS_inv in Hfr.
apply Cof,
Hfr.
Qed.
Admissibility predicate needed by fixp_ind
Lemma DSForall_admissible :
admissible DSForall.
Proof.
intros f Hf.
simpl.
unfold DS_lub.
generalize 1
as m.
generalize dependent f.
cofix Cof.
intros.
rewrite DS_lubn_inv.
destruct (
fCon f (
S m)).
-
destruct s as (?&?&?&?&
Hplus).
constructor;
auto.
+
specialize (
Hplus O).
rewrite plus_O_n in Hplus.
specialize (
Hf x1).
rewrite Hplus in Hf.
now inversion Hf.
+
apply Cof.
intro n.
specialize (
Hplus n).
specialize (
Hf (
n +
x1)).
rewrite Hplus in Hf.
now inversion Hf.
-
constructor.
apply Cof.
intro n.
specialize (
Hf (
n)).
unfold cpred,
pred.
simpl.
destruct (
f n)
eqn:
Hfn.
+
setoid_rewrite Hfn.
now inversion Hf.
+
now do 2
setoid_rewrite Hfn.
Qed.
More general admissibility
Lemma DSForall_admissible2 :
forall D (
f :
D -
C->
DS A),
admissible (
fun s =>
DSForall (
f s)).
Proof.
Induction principle for simple streams defined with FIXP
Lemma DSForall_FIXP :
forall (
F :
DS A -
C->
DS A),
(
forall s,
DSForall s ->
DSForall (
F s)) ->
DSForall (
FIXP (
DS A)
F).
Proof.
Lemma DSForall_app :
forall u v,
DSForall u ->
DSForall v ->
DSForall (
app u v).
Proof.
intros.
remember_ds (
app u v)
as t.
revert_all.
cofix Cof;
intros *
Fu Fv t Ht.
destruct t;
constructor.
-
rewrite <-
eqEps in *.
now eapply Cof with (
u :=
u) (
v :=
v).
-
apply symmetry,
app_cons_elim in Ht as (?&
Hu &?).
rewrite Hu in Fu;
now inv Fu.
-
apply symmetry,
app_cons_elim in Ht as (?& ? &
Ht).
now rewrite Ht.
Qed.
Lemma DSForall_take :
forall n xs,
DSForall xs ->
DSForall (
take n xs).
Proof.
End DS_Forall.
Lemma DSForall_map :
forall {
A B} (
f :
A ->
B)
P s,
DSForall (
fun x =>
P (
f x))
s ->
DSForall P (
MAP f s).
Proof.
clear;
intros.
remember (
MAP f s)
as fs.
apply Oeq_refl_eq in Heqfs.
generalize dependent s.
revert fs.
cofix Cof;
intros *
H Hfs.
destruct fs.
-
constructor.
apply Cof with s;
auto.
now rewrite eqEps.
-
apply symmetry,
map_eq_cons_elim in Hfs as (?&? &
Hs &?&?);
subst.
rewrite Hs in *;
inv H.
constructor;
auto.
apply Cof with (
rem s);
rewrite Hs,
rem_cons;
auto.
Qed.
Lemma DSForall_impl :
forall A (
P Q :
A ->
Prop) (
s :
DS A),
(
forall x :
A,
P x ->
Q x) ->
DSForall P s ->
DSForall Q s.
Proof.
intros ???.
cofix Cof.
destruct s; intros Pq Hf; inv Hf; constructor; cases.
Qed.
Lemma DSForall_and :
forall A (
P Q :
A ->
Prop) (
u :
DS A),
DSForall P u ->
DSForall Q u ->
DSForall (
fun x =>
P x /\
Q x)
u.
Proof.
cofix Cof; intros * Hp Hq.
destruct u; inv Hp; inv Hq; constructor; auto.
Qed.
Lemma DSForall_forall :
forall {
A T} (
P :
T ->
A ->
Prop) (
s :
DS A),
(
forall x,
DSForall (
P x)
s)
<->
DSForall (
fun s =>
forall x,
P x s)
s.
Proof.
split;
revert s;
cofix Cof;
intros *
Hf.
-
destruct s;
constructor;
eauto using DSForall_tl.
+
setoid_rewrite <-
eqEps in Hf;
eauto.
+
intro x.
specialize (
Hf x).
now inv Hf.
-
destruct s;
constructor;
eauto using DSForall_tl.
+
setoid_rewrite <-
eqEps in Hf;
eauto.
+
inv Hf;
auto.
Qed.
Admissibility with dependent predicate on elements of the stream
Lemma DSForall_admissible3 :
forall (
D:
cpo) (
A T :
Type) (
P :
T ->
A ->
Prop) (
f :
T ->
D -
C->
DS A),
@
admissible D (
fun s =>
forall x,
DSForall (
P x) (
f x s)).
Proof.
Lemma DSForall_zip :
forall {
A B C},
forall (
P :
A ->
Prop) (
Q :
B ->
Prop) (
R :
C ->
Prop),
forall op xs ys,
(
forall x y,
P x ->
Q y ->
R (
op x y)) ->
DSForall P xs ->
DSForall Q ys ->
DSForall R (
ZIP op xs ys).
Proof.
intros *
PQ Hp Hq.
remember (
ZIP _ _ _)
as t eqn:
Ht.
apply Oeq_refl_eq in Ht.
revert Hp Hq Ht.
revert xs ys t.
cofix Cof;
intros.
destruct t.
-
constructor;
rewrite <-
eqEps in Ht;
eauto.
-
apply symmetry,
zip_uncons in Ht as (?&?&?&?&
Hx &
Hy &
Ht &?).
rewrite Hx,
Hy in *;
inv Hp;
inv Hq.
constructor;
eauto.
Qed.
Lemma DSForall_zip3 :
forall {
A B C D},
forall (
P :
A ->
Prop) (
Q :
B ->
Prop) (
R :
C ->
Prop) (
S :
D ->
Prop),
forall op xs ys zs,
(
forall x y z,
P x ->
Q y ->
R z ->
S (
op x y z)) ->
DSForall P xs ->
DSForall Q ys ->
DSForall R zs ->
DSForall S (
ZIP3 op xs ys zs).
Proof.