From Coq Require Import FSets.FMapPositive.
From Coq Require Import PArith.
From Velus Require Import Stc.
From Velus Require Import Obc.
From Velus Require Import StcToObc.Translation.
From Velus Require Import Common.
From Velus Require Import CommonTyping.
From Velus Require Import FunctionalEnvironment.
From Coq Require Import List.
Import List.ListNotations.
Open Scope list_scope.
Module Type STC2OBCINVARIANTS
(
Import Ids :
IDS)
(
Import Op :
OPERATORS)
(
Import OpAux :
OPERATORS_AUX Ids Op)
(
Import ComTyp:
COMMONTYPING Ids Op OpAux)
(
Import Cks :
CLOCKS Ids Op OpAux)
(
Import Str :
INDEXEDSTREAMS Ids Op OpAux Cks)
(
Import CE :
COREEXPR Ids Op OpAux ComTyp Cks Str)
(
Import Stc :
STC Ids Op OpAux ComTyp Cks Str CE)
(
Import Obc :
OBC Ids Op OpAux ComTyp)
(
Import Trans :
TRANSLATION Ids Op OpAux Cks CE.Syn Stc.Syn Obc.Syn).
Show that the Obc code that results from translating a Stc
program satisfies the Fusible invariant, and thus that fusion
preserves its semantics.
Lemma Can_write_in_translate_cexp:
forall assign mems e y,
Can_write_in y (
translate_cexp mems assign e) ->
exists oe,
Can_write_in y (
assign oe).
Proof.
induction e using cexp_ind2;
intros *
Hcw;
simpl in *.
-
inv Hcw.
simpl_Exists.
simpl_Forall.
eauto.
-
inv Hcw.
simpl_Exists.
simpl_Forall.
destruct x;
simpl in *;
eauto.
-
eauto.
Qed.
Lemma Is_free_in_tovar:
forall mems x y ty,
Is_free_in_exp (
RCurrent y) (
tovar mems (
x,
ty)) <->
x =
y.
Proof.
unfold tovar;
intros.
cases;
split;
intro HH;
(
inversion_clear HH;
reflexivity ||
subst;
now constructor).
Qed.
Lemma Is_free_current_translate_exp:
forall x mems e,
Is_free_in_exp (
RCurrent x) (
translate_exp mems e) ->
CE.IsF.Is_free_in_exp (
FunctionalEnvironment.Var x)
e.
Proof.
induction e;
simpl;
intro H;
auto with stcfree;
try now inv H.
-
apply Is_free_in_tovar in H;
subst;
auto with stcfree.
-
constructor;
inversion H;
auto.
-
constructor;
inv H;
take (
_ \/
_)
and destruct it;
subst;
auto.
Qed.
Lemma Is_free_last_translate_exp:
forall x mems e,
Is_free_in_exp (
RLast x) (
translate_exp mems e) ->
CE.IsF.Is_free_in_exp (
FunctionalEnvironment.Last x)
e.
Proof.
induction e; simpl; intro H; auto with stcfree; try now inv H.
- cases; inv H.
- inv H. constructor.
- constructor; inversion H; auto.
- constructor; inv H; take (_ \/ _) and destruct it; subst; auto.
Qed.
Lemma Is_free_last_translate_arg:
forall x mems ckvars ck e,
Is_free_in_exp (
RLast x) (
translate_arg mems ckvars ck e) ->
CE.IsF.Is_free_in_exp (
FunctionalEnvironment.Last x)
e.
Proof.
Lemma Is_free_last_translate_cexp:
forall assign x mems e,
(
forall x oe,
Is_free_in_stmt x (
assign oe) ->
Is_free_in_exp x oe) ->
Is_free_in_stmt (
RLast x) (
translate_cexp mems assign e) ->
CE.IsF.Is_free_in_cexp (
FunctionalEnvironment.Last x)
e.
Proof.
Lemma Is_free_last_Control:
forall x mems ck stmt,
Is_free_in_stmt (
RLast x) (
Control mems ck stmt) ->
Is_free_in_stmt (
RLast x)
stmt.
Proof.
induction ck;
intros *
Free;
simpl in *;
auto.
destruct p,
t.
inv Free.
apply IHck in Free.
inv Free.
-
cases;
inv H1.
-
simpl_Exists.
destruct x0;
simpl in *; [|
inv H1].
eapply skip_branches_with_In_det in Hin;
subst;
eauto.
Qed.
Lemma Is_free_last_translate_tc:
forall x mems clkvars tc,
Is_free_in_stmt (
RLast x) (
translate_tc mems clkvars tc) ->
Is_free_in_tc (
FunctionalEnvironment.Last x)
tc.
Proof.
Lemma Can_write_in_Control :
forall x mems ck s,
Can_write_in x (
Control mems ck s) ->
Can_write_in x s.
Proof.
induction ck;
intros *
Cw;
simpl in *;
auto.
destruct p,
t; [
inv Cw|].
eapply IHck in Cw.
inv Cw.
simpl_Exists.
destruct x0;
simpl in *; [|
inv H1].
eapply skip_branches_with_In_det in Hin;
subst;
auto.
Qed.
Lemma Can_write_in_translate_tc:
forall x mems clkvars tc,
Can_write_in (
WCurrent x) (
translate_tc mems clkvars tc) ->
Is_defined_in_tc x tc \/
Is_update_next_in_tc x tc.
Proof.
Lemma Fusible_Control:
forall mems ck s,
(
forall x,
Is_free_in_clock x ck ->
Can_write_in (
WCurrent x)
s \/
Can_write_in (
WReset x)
s ->
False) ->
Fusible s ->
Fusible (
Control mems ck s).
Proof.
induction ck as [|
ck IH i b]; [
now intuition|].
intros *
Hxni Hfce;
simpl.
cases;
auto using Fusible;
apply IH.
-
intros j Hfree Hcw.
apply Hxni with (
x :=
j); [
inversion_clear Hfree;
eauto with stcfree|].
destruct Hcw as [
Hcw|
Hcw]; [
left|
right];
inv Hcw.
1,2:
simpl_Exists;
destruct x;
simpl in *;
try take (
Can_write_in _ _)
and now inv it.
1,2:
apply skip_branches_with_In_det in Hin;
subst;
auto.
-
constructor.
+
apply Forall_forall;
intros [|]
Hin;
simpl;
auto using Fusible.
apply skip_branches_with_In_det in Hin;
subst;
auto.
+
intros *
Hfree;
apply Forall_forall;
intros [|]
Hin;
simpl;
try now inversion 1.
apply skip_branches_with_In_det in Hin;
subst.
inv Hfree.
eauto with stcfree.
+
intros *
Hfree;
apply Forall_forall;
intros [|]
Hin;
simpl;
try now inversion 1.
-
intros j Hfree Hcw.
apply Hxni with (
x :=
j); [
inversion_clear Hfree;
eauto with stcfree|].
destruct Hcw as [
Hcw|
Hcw]; [
left|
right];
inv Hcw.
1,2:
simpl_Exists;
destruct x;
simpl in *;
try take (
Can_write_in _ _)
and now inv it.
1,2:
apply skip_branches_with_In_det in Hin;
subst;
auto.
-
constructor.
+
apply Forall_forall;
intros [|]
Hin;
simpl;
auto using Fusible.
apply skip_branches_with_In_det in Hin;
subst;
auto.
+
intros *
Hfree;
apply Forall_forall;
intros [|]
Hin;
simpl;
try now inversion 1.
apply skip_branches_with_In_det in Hin;
subst.
inv Hfree;
eauto with stcfree.
+
intros *
Hfree;
apply Forall_forall;
intros [|]
Hin;
simpl;
try now inversion 1.
Qed.
Fact Fusible_fold_left_change:
forall A f (
xs:
list A)
acc1 acc2,
(
Fusible acc1 ->
Fusible acc2) ->
(
forall x,
Is_free_in_stmt (
RLast x)
acc2 ->
Is_free_in_stmt (
RLast x)
acc1) ->
Fusible (
fold_left (
fun i x =>
Comp (
f x)
i)
xs acc1) ->
Fusible (
fold_left (
fun i x =>
Comp (
f x)
i)
xs acc2).
Proof.
induction xs;
intros *
Acc Last Fus;
simpl in *;
auto.
eapply IHxs in Fus;
eauto.
+
intros *
F.
inv F.
econstructor;
eauto.
intros *
Cw L.
eapply H3;
eauto.
+
intros *
F.
inv F;
eauto using Is_free_in_stmt.
Qed.
Fact Fusible_fold_left_shift:
forall A f (
xs :
list A)
iacc,
Forall' (
fun stmts stmt =>
forall x,
Is_free_in_stmt (
RLast x)
stmt -> ~
Exists (
Can_write_in (
WCurrent x))
stmts) (
iacc::
map f xs) ->
Fusible (
fold_left (
fun i x =>
Comp (
f x)
i)
xs Skip) ->
Fusible iacc ->
Fusible (
fold_left (
fun i x =>
Comp (
f x)
i)
xs iacc).
Proof.
induction xs as [|
x xs IH];
intros *
Sch Fus1 Fus2; [
now intuition|].
repeat take (
Forall'
_ (
_ ::
_))
and inv it.
simpl in *.
apply IH;
auto.
-
constructor;
auto.
intros * ??.
take (
Is_free_in_stmt _ (
Comp _ _))
and inv it.
+
take (
forall x,
_ -> ~
Exists _ _)
and eapply it;
eauto.
+
take (
forall x,
_ -> ~
Exists _ (
_::
_))
and eapply it;
eauto.
-
eapply Fusible_fold_left_change in Fus1;
eauto.
+
intros.
constructor.
+
intros *
L.
inv L.
-
constructor;
auto.
+
clear -
Fus1.
induction xs;
simpl in *.
*
now inv Fus1.
*
eapply IHxs.
eapply Fusible_fold_left_change in Fus1;
eauto.
--
intros F.
now inv F.
--
intros *
F.
inv F;
eauto using Is_free_in_stmt.
+
intros *
Cw Free.
eapply H1;
eauto.
Qed.
Lemma Fusible_translate_cexp:
forall mems assign e,
(
forall e,
Fusible (
assign e)) ->
(
forall x,
Is_free_in_cexp (
FunctionalEnvironment.Var x)
e ->
forall oe, ~
Can_write_in (
WCurrent x) (
assign oe) /\ ~
Can_write_in (
WReset x) (
assign oe)) ->
(
forall x,
Is_free_in_cexp (
FunctionalEnvironment.Last x)
e ->
forall oe, ~
Can_write_in (
WReset x) (
assign oe)) ->
Fusible (
translate_cexp mems assign e).
Proof.
induction e using cexp_ind2';
intros *
Fus Free FreeL;
eauto.
-
destruct x.
simpl;
constructor.
+
simpl_Forall.
eapply H;
eauto.
*
intros *
F.
eapply Free.
constructor.
solve_Exists.
*
intros *
F.
eapply FreeL.
constructor.
solve_Exists.
+
intros *
Hfree'.
simpl_Forall.
intros [
Cw|
Cw].
1,2:
eapply Can_write_in_translate_cexp in Cw as (?&
Cw).
1,2:
eapply Free in Cw;
eauto;
cases;
inv Hfree';
constructor.
+
intros *
Hfree'.
simpl_Forall.
intros Cw.
eapply Can_write_in_translate_cexp in Cw as (?&
Cw).
eapply Free in Cw;
eauto;
cases;
inv Hfree';
constructor.
-
simpl;
constructor.
+
simpl_Forall.
destruct x;
simpl in *.
*
eapply H;
eauto.
--
intros *
F.
eapply Free.
apply FreeEcase_branches.
solve_Exists.
--
intros *
F.
eapply FreeL.
apply FreeEcase_branches.
solve_Exists.
*
eapply IHe;
eauto.
--
intros *
F.
eapply Free;
eauto using Is_free_in_cexp.
--
intros *
F.
eapply FreeL;
eauto using Is_free_in_cexp.
+
intros *
Hfree'.
simpl_Forall.
intros Cw.
eapply Is_free_current_translate_exp in Hfree'.
destruct Cw as [
Cw|
Cw],
x0;
simpl in *.
all:
eapply Can_write_in_translate_cexp in Cw as (?&
Cw).
all:
eapply Free in Cw;
eauto using Is_free_in_cexp.
+
intros *
Hfree'.
simpl_Forall.
intros Cw.
eapply Is_free_last_translate_exp in Hfree'.
destruct x0;
simpl in *.
all:
eapply Can_write_in_translate_cexp in Cw as (?&
Cw).
all:
eapply FreeL in Cw;
eauto using Is_free_in_cexp.
Qed.
Lemma translate_tcs_Fusible {
prefs} :
forall (
P: @
Stc.Syn.program prefs) Γ
nexts mems clkvars inputs tcs,
wc_env (
idfst Γ) ->
NoDupMembers Γ ->
Forall (
wc_trconstr P Γ)
tcs ->
NoDup (
defined tcs) ->
Is_well_sch inputs nexts tcs ->
(
forall x,
PS.In x mems -> ~
Is_variable_in x tcs /\ ~
In x inputs) ->
(
forall x,
In x nexts ->
PS.In x mems) ->
(
forall x ck,
In (
x, (
ck,
true)) Γ ->
PS.In x mems) ->
(
forall x,
In x inputs \/
In x nexts -> ~
Is_defined_in x tcs) ->
Fusible (
translate_tcs mems clkvars tcs).
Proof.
Lemma reset_mems_Fusible:
forall mems,
Fusible (
reset_mems mems).
Proof.
intro;
unfold reset_mems.
assert (
Fusible Skip)
as Hf by auto using Fusible.
revert Hf;
generalize Skip.
induction mems as [|(
x, (
c,
ck))];
intros s Hf;
simpl;
auto using Fusible.
eapply IHmems.
repeat constructor;
auto.
intros *
Cw Free.
inv Free.
cases;
inv H1.
Qed.
Local Hint Resolve reset_mems_Fusible :
obcinv.
Lemma reset_insts_Fusible:
forall blocks,
Fusible (
reset_insts blocks).
Proof.
intro;
unfold reset_insts.
assert (
Fusible Skip)
as Hf by constructor.
revert Hf;
generalize Skip.
induction blocks as [|(
x,
f)];
intros s Hf;
simpl;
auto using Fusible.
eapply IHblocks.
repeat constructor;
auto.
intros *
Cw Free.
inv Free.
inv H1.
Qed.
Local Hint Resolve reset_insts_Fusible :
obcinv.
Theorem ProgramFusible_translate:
forall P,
wc_program P ->
Well_scheduled P ->
ProgramFusible (
translate P).
Proof.
intros [];
induction systems0 as [|
s];
intros *
WC Wsch;
inversion_clear WC as [|?? (?&?&?&
WCb)];
inversion_clear Wsch as [|???
Wsch'];
simpl;
constructor;
auto;
try now apply IHsystems0.
unfold ClassFusible;
simpl.
repeat constructor;
simpl;
auto with obcinv.
assert (
NoDup (
defined (
s_tcs s)))
by apply s_nodup_defined.
eapply translate_tcs_Fusible;
eauto with obcinv.
-
clear -
H1.
simpl_app.
erewrite ?
map_map,
map_ext with (
l:=
s_in _),
map_ext with (
l:=
s_vars _),
map_ext with (
l:=
s_out _),
map_ext with (
l:=
s_lasts _),
map_ext with (
l:=
s_nexts _);
eauto.
all:
intros;
destruct_conjs;
auto.
-
rewrite fst_NoDupMembers.
simpl_app.
erewrite ?
map_map,
map_ext with (
l:=
s_in _),
map_ext with (
l:=
s_vars _),
map_ext with (
l:=
s_out _),
map_ext with (
l:=
s_lasts _),
map_ext with (
l:=
s_nexts _);
eauto.
apply s_nodup.
all:
intros;
destruct_conjs;
auto.
-
intros *
In.
apply ps_from_list_In in In.
split;
intros In2.
+
apply Is_variable_in_variables in In2.
rewrite <-
s_vars_out_in_tcs in In2.
pose proof (
s_nodup s)
as Nd.
apply NoDup_app_r in Nd.
rewrite app_assoc in Nd.
eapply NoDup_app_In;
eauto.
now rewrite <-
map_app.
+
eapply NoDup_app_In;
eauto using s_nodup.
rewrite <-
map_app.
auto using in_or_app.
-
intros *
L.
apply ps_from_list_In.
rewrite map_app.
auto using in_or_app.
-
intros *
In.
apply ps_from_list_In.
rewrite map_app,
in_app_iff.
left.
rewrite ?
in_app_iff in In.
destruct In as [
In|[
In|
In]];
solve_In.
-
intros * [
In|
In].
+
apply s_ins_not_def,
fst_InMembers;
auto.
+
rewrite Is_defined_in_defined,
s_defined, <-
s_lasts_in_tcs.
intros ?.
pose proof (
s_nodup_variables_lasts_nexts s)
as ND.
rewrite map_app,
app_assoc in ND.
eapply NoDup_app_In in ND;
eauto.
-
intros *
Cw _.
clear -
Cw.
remember (
s_lasts _ ++
s_nexts _)
as xs.
clear Heqxs.
unfold reset_mems in *.
assert (
Can_write_in (
WCurrent x0)
Skip ->
False)
as Acc by (
intros Cw';
inv Cw').
revert Acc Cw;
generalize Skip.
induction xs as [|(
x,
f)];
intros *
Acc Cw;
simpl in *;
eauto.
eapply IHxs in Cw;
eauto.
intros Cw1.
inv Cw1;
auto.
cases;
inv H1.
Qed.
Translating gives No_Overwrites Obc.
Lemma Can_write_in_var_Control:
forall mems ck s x,
Can_write_in_var x (
Control mems ck s) ->
Can_write_in_var x s.
Proof.
induction ck;
simpl;
auto.
destruct p,
t as [|].
-
inversion 1.
-
intros *
Cw;
apply IHck in Cw;
inv Cw.
take (
Exists _ _)
and apply Exists_exists in it as ([|] &
Hin &
Cw);
simpl in *;
try now inv Cw.
apply skip_branches_with_In_det in Hin;
subst;
auto.
Qed.
Corollary Can_write_in_var_Control':
forall mems ck s x enums Γ,
wt_clock enums Γ
ck ->
Can_write_in_var x (
Control mems ck s) <->
Can_write_in_var x s.
Proof.
Lemma No_Overwrites_Control:
forall mems ck s enums Γ,
wt_clock enums Γ
ck ->
No_Overwrites (
Control mems ck s) <->
No_Overwrites s.
Proof.
Lemma Can_write_in_var_translate_cexp:
forall mems e x assign,
Can_write_in_var x (
translate_cexp mems assign e) ->
exists oe,
Can_write_in_var x (
assign oe).
Proof.
induction e using cexp_ind2;
simpl;
try setoid_rewrite Can_write_in_var_Switch;
try setoid_rewrite Exists_exists.
-
intros * (
os &
Hin &
Cw).
simpl_In.
simpl_Forall.
eauto.
-
intros * (
os &
Hin &
Cw).
simpl_In.
simpl_Forall.
destruct x0;
simpl in *;
eauto.
-
intros;
eauto.
Qed.
Lemma No_Overwrites_translate_cexp:
forall mems assign e,
(
forall oe,
No_Overwrites (
assign oe)) ->
No_Overwrites (
translate_cexp mems assign e).
Proof.
induction e using cexp_ind2;
intros *
NO;
simpl;
auto.
1,2:
constructor;
simpl_Forall;
eauto.
destruct x;
simpl in *;
auto.
Qed.
Lemma Can_write_in_var_translate_tc_Is_variable_in_tc:
forall mems clkvars tc x,
Can_write_in_var x (
translate_tc mems clkvars tc) ->
Is_variable_in_tc x tc.
Proof.
Lemma Can_write_in_var_translate_tcs_Is_variable_in:
forall mems clkvars tcs x,
Can_write_in_var x (
translate_tcs mems clkvars tcs) ->
Is_variable_in x tcs.
Proof.
Lemma translate_tcs_No_Overwrites {
prefs} :
forall clkvars mems inputs nexts tcs (
P: @
Stc.Syn.program prefs) Γ,
NoDup (
variables tcs) ->
Forall (
wt_trconstr P Γ)
tcs ->
Is_well_sch inputs nexts tcs ->
No_Overwrites (
translate_tcs mems clkvars tcs).
Proof.
Lemma not_Can_write_in_var_reset_insts:
forall x subs,
~
Can_write_in_var x (
reset_insts subs).
Proof.
unfold reset_insts;
intros.
assert (~
Can_write_in_var x Skip)
as CWIS by inversion 1.
revert CWIS;
generalize Skip.
induction subs;
simpl;
auto.
intros;
apply IHsubs.
inversion_clear 1
as [| | | | |???
CWI];
try inv CWI;
contradiction.
Qed.
Lemma No_Overwrites_reset_inst:
forall subs,
No_Overwrites (
reset_insts subs).
Proof.
unfold reset_insts;
intros.
assert (
No_Overwrites Skip)
as NOS by constructor.
revert NOS;
generalize Skip.
induction subs;
simpl;
auto.
intros;
apply IHsubs.
constructor;
auto with obcinv.
-
inversion 2;
contradiction.
-
inversion 1;
contradiction.
Qed.
Lemma No_Overwrites_reset_mems:
forall resets,
NoDupMembers resets ->
No_Overwrites (
reset_mems resets).
Proof.
unfold reset_mems;
intros *
Nodup.
assert (
No_Overwrites Skip)
as NOS by constructor.
assert (
forall x,
InMembers x resets -> ~
Can_write_in_var x Skip)
as CWIS by inversion 2.
revert NOS CWIS;
generalize Skip.
induction resets as [|(
x, (
c0,
ck))];
simpl;
auto;
inv Nodup.
intros;
apply IHresets;
auto.
-
constructor;
auto with obcinv.
+
inversion 2;
subst;
eapply CWIS;
eauto.
+
inversion_clear 1;
auto.
-
inversion_clear 2
as [| | | | |???
CWI];
try inv CWI;
subst;
auto.
eapply CWIS;
eauto.
Qed.
Corollary translate_reset_No_Overwrites:
forall b,
No_Overwrites (
translate_reset b).
Proof.
Lemma translate_system_No_Overwrites {
prefs} :
forall s m (
P: @
Stc.Syn.program prefs),
Is_well_sch (
map fst (
s_in s)) (
map fst (
s_nexts s)) (
s_tcs s) ->
Forall
(
wt_trconstr P
(
map (
fun '(
x, (
ty,
_)) => (
x, (
ty,
false))) (
s_in s ++
s_vars s ++
s_out s)
++
map (
fun '(
x, (
_,
ty,
_)) => (
x, (
ty,
true))) (
s_lasts s)
++
map (
fun '(
x, (
_,
ty,
_)) => (
x, (
ty,
false))) (
s_nexts s))) (
s_tcs s) ->
In m (
translate_system s).(
c_methods) ->
No_Overwrites m.(
m_body).
Proof.
Corollary translate_No_Overwrites:
forall P,
Well_scheduled P ->
Stc.Typ.wt_program P ->
Forall_methods (
fun m =>
No_Overwrites m.(
m_body)) (
translate P).
Proof.
The node doesn't write its inputs
Lemma Can_write_in_translate_tc_Is_variable_in_tc:
forall mems clkvars tc x,
Can_write_in_var x (
translate_tc mems clkvars tc) ->
Is_variable_in_tc x tc \/ (
exists ck,
Is_reset_state_in_tc x ck tc) \/
Is_update_last_in_tc x tc.
Proof.
Lemma Can_write_in_translate_tcs_Is_variable_in:
forall mems clkvars tcs x,
Can_write_in_var x (
translate_tcs mems clkvars tcs) ->
Is_variable_in x tcs \/ (
exists ck,
Is_reset_state_in x ck tcs) \/
Is_update_last_in x tcs.
Proof.
unfold translate_tcs.
intros mems clkvars tcs x.
match goal with |- ?
P -> ?
Q =>
cut (
P -> (
Q \/
Can_write_in_var x Skip))
end.
now intros HH H;
apply HH in H as [?|?];
auto;
inv H.
generalize Skip.
induction tcs as [|
tc tcs IH];
simpl;
intros s HH;
auto.
apply IH in HH as [
HH|
HH]; [|
inv HH];
auto.
-
left.
destruct HH as [
HH|[(
ck&
HH)|
HH]]; [
left|
right;
left|
right;
right];
try exists ck;
right;
auto.
-
left.
apply Can_write_in_translate_tc_Is_variable_in_tc in H1 as [?|[(
ck&?)|?]];
[
left|
right;
left|
right;
right];
try exists ck;
left;
auto.
Qed.
Lemma translate_system_cannot_write_inputs:
forall s m,
In m (
translate_system s).(
c_methods) ->
Forall (
fun x => ~
Can_write_in_var x m.(
m_body)) (
map fst m.(
m_in)).
Proof.
Corollary translate_cannot_write_inputs:
forall P,
Forall_methods (
fun m =>
Forall (
fun x => ~
Can_write_in_var x (
m_body m)) (
map fst (
m_in m)))
(
translate P).
Proof.
End STC2OBCINVARIANTS.
Module Stc2ObcInvariantsFun
(
Ids :
IDS)
(
Op :
OPERATORS)
(
OpAux :
OPERATORS_AUX Ids Op)
(
ComTyp:
COMMONTYPING Ids Op OpAux)
(
Cks :
CLOCKS Ids Op OpAux)
(
Str :
INDEXEDSTREAMS Ids Op OpAux Cks)
(
CE :
COREEXPR Ids Op OpAux ComTyp Cks Str)
(
Stc :
STC Ids Op OpAux ComTyp Cks Str CE)
(
Obc :
OBC Ids Op OpAux ComTyp)
(
Trans :
TRANSLATION Ids Op OpAux Cks CE.Syn Stc.Syn Obc.Syn)
<:
STC2OBCINVARIANTS Ids Op OpAux ComTyp Cks Str CE Stc Obc Trans.
Include STC2OBCINVARIANTS Ids Op OpAux ComTyp Cks Str CE Stc Obc Trans.
End Stc2ObcInvariantsFun.