From Coq Require Import Datatypes List.
Import List.ListNotations.
From Velus Require Import Lustre.Denot.Cpo CommonTactics.
Require Import CommonDS SDfuns.
Effactement des absences dans les flots
* pour obtenir une sémantique de Kahn
définitions identiques à celles de Safe.v
Definition safe_DS {
A} :
DS (
sampl A) ->
Prop :=
DSForall (
fun v =>
match v with err _ =>
False |
_ =>
True end).
Definition safe_ty {
A} :
DS (
sampl A) ->
Prop :=
DSForall (
fun v =>
match v with err error_Ty =>
False |
_ =>
True end).
Definition safe_cl {
A} :
DS (
sampl A) ->
Prop :=
DSForall (
fun v =>
match v with err error_Cl =>
False |
_ =>
True end).
Definition safe_op {
A} :
DS (
sampl A) ->
Prop :=
DSForall (
fun v =>
match v with err error_Op =>
False |
_ =>
True end).
Lemma nabs_dec :
forall A (
x :
sampl A), {
x <>
abs} + {~
x <>
abs}.
Proof.
intros ? []; auto; now left. Qed.
Fonction d'effacement des absences d'un flot
Definition ea {
A} :
DS (
sampl A) -
C->
DS (
sampl A).
refine (
FILTER (
fun v =>
v <>
abs)
_).
intros [];
auto;
now left.
Defined.
Lemma ea_cons :
forall A (
x :
sampl A)
xs,
ea (
cons x xs)
==
match x with
|
abs =>
ea xs
|
_ =>
cons x (
ea xs)
end.
Proof.
Lemma ea_is_cons :
forall A (
xs :
DS (
sampl A)),
is_cons (
ea xs) ->
isConP (
fun v =>
v <>
abs)
xs.
Proof.
Lemma isConP_is_cons :
forall D (
P:
D->
Prop)
xs,
isConP P xs ->
is_cons xs.
Proof.
induction 1; auto; now constructor.
Qed.
Theorem erase_unop :
forall A B (
op:
A->
option B) (
xs :
DS (
sampl A)),
ea (
sunop op xs) ==
sunop op (
ea xs).
Proof.
Lemma erase_sbinop_1 :
forall A B C (
op:
A->
B->
option C)
xs ys,
safe_DS (
sbinop op xs ys) ->
ea (
sbinop op xs ys) <=
sbinop op (
ea xs) (
ea ys).
Proof.
intros *
Hs.
apply DSle_rec_eq2 with
(
R :=
fun U V =>
(
exists xs ys,
safe_DS (
sbinop op xs ys)
/\
U ==
ea (
sbinop op xs ys)
/\
V ==
sbinop op (
ea xs) (
ea ys))
).
3:
eauto.
intros * ?
Eq1 Eq2;
setoid_rewrite <-
Eq1;
setoid_rewrite <-
Eq2;
eauto.
clear;
intros U V Hc (
xs &
ys &
Hs &
Hu &
Hv).
rewrite Hu,
Hv in *.
apply ea_is_cons in Hc as Hcp.
remember_ds (
sbinop op xs ys)
as rs.
revert dependent xs.
revert dependent ys.
revert dependent U.
revert dependent V.
induction Hcp;
intros.
{
rewrite <-
eqEps in *;
eauto 2. }
-
assert (
a =
abs);
subst.
{
inv Hs.
cases.
contradict H.
congruence. }
destruct (@
is_cons_elim _ xs)
as (
x &
xs' &
Hxs).
{
eapply proj1,
sbinop_is_cons;
rewrite <-
Hrs;
auto. }
destruct (@
is_cons_elim _ ys)
as (
y &
ys' &
Hys).
{
eapply proj2,
sbinop_is_cons;
rewrite <-
Hrs;
auto. }
rewrite Hxs,
Hys, 3
ea_cons in *.
rewrite sbinop_eq in Hrs.
apply Con_eq_simpl in Hrs as [].
inv Hs;
cases;
congruence.
-
destruct (@
is_cons_elim _ xs)
as (
x &
xs' &
Hxs).
{
eapply proj1,
sbinop_is_cons;
rewrite <-
Hrs;
auto. }
destruct (@
is_cons_elim _ ys)
as (
y &
ys' &
Hys).
{
eapply proj2,
sbinop_is_cons;
rewrite <-
Hrs;
auto. }
rewrite Hxs,
Hys, 3
ea_cons in *.
rewrite sbinop_eq in *.
apply Con_eq_simpl in Hrs as [?
Hrs].
inv Hs.
destruct x,
y;
try tauto.
rewrite sbinop_eq,
Hrs in *.
cases_eqn HH;
inv HH.
rewrite 2
first_cons;
split;
auto.
setoid_rewrite Hv.
setoid_rewrite Hu.
setoid_rewrite Hrs.
rewrite 2
rem_cons;
eauto.
Qed.
Lemma erase_sbinop_2 :
forall A B C (
op:
A->
B->
option C)
xs ys,
safe_DS (
sbinop op xs ys) ->
sbinop op (
ea xs) (
ea ys) <=
ea (
sbinop op xs ys).
Proof.
intros *
Hs.
apply DSle_rec_eq2 with
(
R :=
fun U V =>
(
exists xs ys,
safe_DS (
sbinop op xs ys)
/\
U ==
sbinop op (
ea xs) (
ea ys)
/\
V ==
ea (
sbinop op xs ys))
).
3:
eauto.
intros * ?
Eq1 Eq2;
setoid_rewrite <-
Eq1;
setoid_rewrite <-
Eq2;
eauto.
clear;
intros U V Hc (
xs &
ys &
Hs &
Hu &
Hv).
rewrite Hu,
Hv in *.
apply sbinop_is_cons in Hc as [
Hc1 Hc2].
apply ea_is_cons in Hc1.
revert dependent ys.
revert U V.
induction Hc1;
intros.
-
rewrite <-
eqEps in *;
apply IHHc1;
auto.
-
apply ea_is_cons in Hc2 as Hc2'.
induction Hc2'.
+
rewrite <-
eqEps in *;
apply IHHc2';
auto.
+
rewrite sbinop_eq in *.
inv Hs.
cases_eqn HH;
subst.
2:
contradict H0;
congruence.
repeat rewrite ea_cons in *.
eapply IHHc1;
auto.
+
repeat rewrite ea_cons in *.
repeat rewrite sbinop_eq in *.
inv Hs.
cases_eqn HH;
subst;
try congruence.
repeat rewrite ea_cons in *.
rewrite sbinop_eq in *.
cases_eqn HH;
subst;
try congruence.
inv HH2;
inv HH.
rewrite 2
first_cons;
split;
auto.
do 2
esplit;
rewrite Hu,
Hv, 2
rem_cons;
eauto.
-
apply ea_is_cons in Hc2 as Hc2'.
induction Hc2'.
+
rewrite <-
eqEps in *;
apply IHHc2';
auto.
+
rewrite sbinop_eq in *.
inv Hs.
cases_eqn HH;
subst.
all:
contradict H0;
congruence.
+
repeat rewrite ea_cons in *.
repeat rewrite sbinop_eq in *.
inv Hs.
cases_eqn HH;
subst;
try congruence.
repeat rewrite ea_cons in *.
rewrite sbinop_eq in *.
cases_eqn HH;
subst;
try congruence.
inv HH2;
inv HH.
rewrite 2
first_cons;
split;
auto.
do 2
esplit;
rewrite Hu,
Hv, 2
rem_cons;
eauto.
Qed.
Theorem erase_sbinop :
forall A B C (
op:
A->
B->
option C)
xs ys,
safe_DS (
sbinop op xs ys) ->
sbinop op (
ea xs) (
ea ys) ==
ea (
sbinop op xs ys).
Proof.
Lemma erase_fby1 :
forall A v (
xs ys :
DS (
sampl A)),
safe_DS (
fby1 (
Some v)
xs ys) ->
ea (
fby1 (
Some v)
xs ys) <=
cons (
pres v) (
ea ys).
Proof.
intros *
Hs.
apply DSle_rec_eq2 with
(
R :=
fun U V =>
(
exists v xs ys,
safe_DS (
fby1 (
Some v)
xs ys)
/\
U ==
ea (
fby1 (
Some v)
xs ys)
/\
V ==
cons (
pres v) (
ea ys))
\/
(
exists xs ys,
safe_DS (
fby1AP None xs ys)
/\
U ==
ea (
fby1AP None xs ys)
/\
V ==
ea ys)
).
3:
eauto 12.
intros * ?
Eq1 Eq2;
setoid_rewrite <-
Eq1;
setoid_rewrite <-
Eq2;
eauto 12.
clear;
intros U V Hc [(
v &
xs &
ys &
Sf &
Hu &
Hv) | (
xs &
ys &
Sf &
Hu &
Hv)].
-
rewrite Hu,
Hv in *.
apply ea_is_cons in Hc as Hcp.
remember_ds (
fby1 (
Some v)
xs ys)
as rs.
revert dependent xs.
revert dependent ys.
revert dependent U.
revert dependent V.
revert dependent v.
induction Hcp;
intros.
{
rewrite <-
eqEps in *;
eauto 2. }
all:
destruct (@
is_cons_elim _ xs)
as (
x &
xs' &
Hxs);
[
eapply fby1_cons;
rewrite <-
Hrs;
eauto |
rewrite Hxs in *].
+
assert (
a =
abs);
subst.
{
apply Decidable.not_not in H;
auto.
unfold Decidable.decidable.
destruct a;
auto;
right;
congruence. }
rewrite fby1_eq in Hrs.
destruct x;
apply Con_eq_simpl in Hrs as [?
Hrs];
try congruence.
rewrite ea_cons in *.
all:
destruct (@
is_cons_elim _ ys)
as (
y &
ys' &
Hys);
[
eapply fby1AP_cons,
isConP_is_cons;
rewrite <-
Hrs;
eauto |
rewrite Hys in *].
inversion_clear Sf as [|???
Sf'].
rewrite fby1AP_eq in Hrs.
destruct y;
rewrite ea_cons in *;
eauto 2.
all:
exfalso;
clear IHHcp.
all:
destruct (@
is_cons_elim _ s)
as (
vs &
s' &
Hs);
[
eapply isConP_is_cons;
eauto |
rewrite Hs in *].
all:
apply symmetry,
map_eq_cons_elim in Hrs as (?&?&?&?&?);
subst;
now inversion Sf'.
+
inversion_clear Sf as [|???
Sf'].
rewrite fby1_eq in Hrs.
destruct a,
x;
apply Con_eq_simpl in Hrs as [
HH Ht];
inversion_clear HH;
try (
tauto ||
congruence).
rewrite ea_cons in *.
rewrite 2
first_cons;
split;
auto.
setoid_rewrite Hu.
setoid_rewrite Hv.
setoid_rewrite rem_cons.
setoid_rewrite Ht.
rewrite Ht in Sf'.
right.
exists xs',
ys.
split;
auto.
-
rewrite Hu,
Hv in *.
destruct (@
is_cons_elim _ ys)
as (
y &
ys' &
Hys);
[
eapply fby1AP_cons,
isConP_is_cons,
ea_is_cons;
eauto
|
rewrite Hys in *].
rewrite fby1AP_eq in *.
destruct y;
rewrite ea_cons in *.
1,3:
destruct (@
is_cons_elim _ xs)
as (
x &
xs' &
Hxs);
[
eapply map_is_cons,
isConP_is_cons,
ea_is_cons,
Hc
|
rewrite Hxs,
map_eq_cons in *];
now inversion_clear Sf.
{
clear Hys ys.
rename a into v.
rename ys'
into ys.
apply ea_is_cons in Hc as Hcp.
remember_ds (
fby1 (
Some v)
xs ys)
as rs.
revert dependent xs.
revert dependent ys.
revert dependent U.
revert dependent V.
revert dependent v.
induction Hcp;
intros.
{
rewrite <-
eqEps in *;
eauto 2. }
all:
destruct (@
is_cons_elim _ xs)
as (
x &
xs' &
Hxs);
[
eapply fby1_cons;
rewrite <-
Hrs;
eauto |
rewrite Hxs in *].
+
assert (
a =
abs);
subst.
{
apply Decidable.not_not in H;
auto.
unfold Decidable.decidable.
destruct a;
auto;
right;
congruence. }
rewrite fby1_eq in Hrs.
destruct x;
apply Con_eq_simpl in Hrs as [?
Hrs];
try congruence.
rewrite ea_cons in *.
all:
destruct (@
is_cons_elim _ ys)
as (
y &
ys' &
Hys);
[
eapply fby1AP_cons,
isConP_is_cons;
rewrite <-
Hrs;
eauto |
rewrite Hys in *].
inversion_clear Sf as [|???
Sf'].
rewrite fby1AP_eq in Hrs.
destruct y;
rewrite ea_cons in *;
eauto 2.
all:
exfalso;
clear IHHcp.
all:
destruct (@
is_cons_elim _ s)
as (
vs &
s' &
Hs);
[
eapply isConP_is_cons;
eauto |
rewrite Hs in *].
all:
apply symmetry,
map_eq_cons_elim in Hrs as (?&?&?&?&?);
subst;
now inversion Sf'.
+
inversion_clear Sf as [|???
Sf'].
rewrite fby1_eq in Hrs.
destruct a,
x;
apply Con_eq_simpl in Hrs as [
HH Ht];
inversion_clear HH;
try (
tauto ||
congruence).
rewrite ea_cons in *.
rewrite 2
first_cons;
split;
auto.
setoid_rewrite Hu.
setoid_rewrite Hv.
setoid_rewrite rem_cons.
setoid_rewrite Ht.
rewrite Ht in Sf'.
right.
exists xs',
ys.
split;
auto.
}
Qed.
Theorem erase_fby :
forall A (
xs ys :
DS (
sampl A)),
safe_DS (
fby xs ys) ->
ea (
fby xs ys) <=
app (
ea xs) (
ea ys).
Proof.
intros *
Hs.
remember_ds (
ea (
fby xs ys))
as U.
remember_ds (
app (
ea xs) (
ea ys))
as V.
revert_all;
cofix Cof;
intros.
destruct U as [|
u U]; [|
clear Cof].
{
constructor;
rewrite <-
eqEps in *;
eapply Cof;
eauto. }
remember_ds (
fby xs ys)
as t.
apply symmetry in HU as HU2.
apply cons_is_cons,
ea_is_cons in HU2.
rewrite HU,
HV.
clear HU HV U V u.
revert dependent xs.
revert dependent ys.
induction HU2;
intros.
{
rewrite <-
eqEps in *;
auto. }
all:
destruct (@
is_cons_elim _ xs)
as (
x &
xs' &
Hxs);
[
eapply fby_cons;
rewrite <-
Ht;
eauto |
rewrite Hxs in *].
-
assert (
a =
abs);
subst.
{
apply Decidable.not_not in H;
auto.
unfold Decidable.decidable.
destruct a;
auto;
right;
congruence. }
rewrite fby_eq in Ht.
destruct x;
apply Con_eq_simpl in Ht as [?
Ht];
try congruence.
all:
destruct (@
is_cons_elim _ ys)
as (
y &
ys' &
Hys);
[
eapply fbyA_cons,
isConP_is_cons;
rewrite <-
Ht;
eauto |
rewrite Hys in *].
inversion_clear Hs as [|???
Hs'].
rewrite fbyA_eq in Ht.
destruct y;
rewrite 3
ea_cons;
auto.
all:
destruct (@
is_cons_elim _ s)
as (
vs &
s' &
Hs);
[
eapply isConP_is_cons;
eauto |
rewrite Hs in *].
all:
apply symmetry,
map_eq_cons_elim in Ht as (?&?&?&?&?);
subst;
now inversion Hs'.
-
inversion_clear Hs as [|???
Hs'].
rewrite fby_eq in Ht.
destruct a,
x;
try (
tauto ||
congruence).
all:
apply Con_eq_simpl in Ht as [
HH Ht];
try congruence.
inversion_clear HH.
rewrite 2
ea_cons,
app_cons.
apply cons_le_compat;
auto.
clear -
Ht Hs'.
remember_ds (
ea s)
as U.
remember_ds (
ea ys)
as V.
revert_all;
cofix Cof;
intros.
destruct U as [|
u U]; [|
clear Cof].
{
constructor;
rewrite <-
eqEps in *;
eapply Cof;
eauto. }
destruct (@
is_cons_elim _ ys)
as (
y &
ys' &
Hys);
[
eapply fby1AP_cons,
isConP_is_cons,
ea_is_cons;
rewrite <-
Ht, <-
HU;
eauto
|
rewrite Hys in *].
rewrite fby1AP_eq in Ht.
destruct y;
rewrite Ht in *.
2:
rewrite HU,
HV,
ea_cons,
erase_fby1;
now auto.
all:
destruct (@
is_cons_elim _ xs')
as (
x &
xs &
Hxs);
[
eapply map_is_cons,
isConP_is_cons,
ea_is_cons;
rewrite <-
HU;
eauto
|
rewrite Hxs,
map_eq_cons in *;
now inversion Hs'].
Qed.
Theorem erase_fby_inf :
forall A (
xs ys :
DS (
sampl A)),
infinite (
fby xs ys) ->
safe_DS (
fby xs ys) ->
ea (
fby xs ys) ==
app (
ea xs) (
ea ys).
Abort.