From Velus Require Import Stc.
From Velus Require Import Obc.
From Velus Require Import StcToObc.Translation.
From Velus Require Import StcToObc.Stc2ObcTyping.
From Velus Require Import VelusMemory.
From Velus Require Import Common.
From Velus Require Import CommonTyping.
From Velus Require Import Environment.
From Velus Require Import FunctionalEnvironment.
From Coq Require Import Lia.
From Coq Require Import List.
Import List.ListNotations.
From Coq Require Import Setoid Morphisms.
Open Scope nat.
Open Scope list.
Module Type CORRECTNESS
(
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)
(
Import TransTyp :
STC2OBCTYPING Ids Op OpAux ComTyp Cks Str CE Stc Obc Trans).
Inductive eq_if_present:
svalue ->
option value ->
Prop :=
|
EqP:
forall v,
eq_if_present (
present v) (
Some v)
|
EqA:
forall v,
eq_if_present absent v.
Global Hint Constructors eq_if_present :
obcsem.
Definition value_to_option (
v:
svalue) :
option value :=
match v with
|
absent =>
None
|
present c =>
Some c
end.
Definition equiv_env (
in_domain:
var_last ->
Prop) (
R:
env)
(
mems:
PS.t) (
me:
menv) (
ve:
venv) :
Prop :=
forall x v,
in_domain x ->
sem_var_instant R x v ->
eq_if_present v (
match x with
|
FunctionalEnvironment.Var x =>
if PS.mem x mems then find_val x me else Env.find x ve
|
Last x =>
find_val x me
end).
Lemma equiv_env_map:
forall (
in_dom1 in_dom2:
var_last ->
Prop)
R mems me ve,
(
forall x,
in_dom2 x ->
in_dom1 x) ->
equiv_env in_dom1 R mems me ve ->
equiv_env in_dom2 R mems me ve.
Proof.
unfold equiv_env;
intros ???????
Eq ????.
apply Eq;
auto.
Qed.
Ltac weaken_equiv_env_with tac :=
match goal with
H:
equiv_env ?
in_dom1 ?
R ?
mems ?
me ?
ve
|-
equiv_env ?
in_dom2 ?
R ?
mems ?
me ?
ve =>
eapply equiv_env_map; [|
exact H];
tac
end.
Tactic Notation "
weaken_equiv_env" "
with"
tactic(
tac) :=
weaken_equiv_env_with tac.
Tactic Notation "
weaken_equiv_env" :=
weaken_equiv_env with now (
constructor;
auto with stcfree).
Global Hint Extern 4 (
equiv_env _ _ _ _ _) =>
weaken_equiv_env :
obcsem stcfree.
Lemma eq_if_present_present:
forall vo c,
eq_if_present (
present c)
vo <->
vo =
Some c.
Proof.
simpl; split.
- now inversion 1.
- intros ->; auto with obcsem.
Qed.
Ltac split_env_assumption :=
match goal with
|
Equiv:
context Is_free_in_exp [
_],
Hvar:
sem_var_instant _ _ _ |-
_ =>
apply Equiv in Hvar; [|
solve [
constructor;
auto]]
|
Equiv:
context Is_free_in_clock [
_],
Hvar:
sem_var_instant _ _ _ |-
_ =>
apply Equiv in Hvar; [|
solve [
constructor;
auto]]
end.
Inductive Is_present_in (
mems:
PS.t) (
me:
menv) (
ve:
venv):
clock ->
Prop :=
|
IsCbase:
Is_present_in mems me ve Cbase
|
IsCon:
forall ck x b t,
Is_present_in mems me ve ck ->
exp_eval me ve (
tovar mems (
x,
t)) (
Some (
Venum b)) ->
Is_present_in mems me ve (
Con ck x (
t,
b)).
Inductive Is_absent_in (
mems:
PS.t) (
me:
menv) (
ve:
venv):
clock ->
Prop :=
|
IsAbs1:
forall ck x v,
Is_absent_in mems me ve ck ->
Is_absent_in mems me ve (
Con ck x v)
|
IsAbs2:
forall ck x b b'
t,
Is_present_in mems me ve ck ->
exp_eval me ve (
tovar mems (
x,
t)) (
Some (
Venum b')) ->
b' <>
b ->
Is_absent_in mems me ve (
Con ck x (
t,
b)).
Global Hint Constructors Is_present_in Is_absent_in :
obcsem.
Arguments tovar:
simpl never.
Section ExprClock.
Variable mems:
PS.t.
Variable R:
env.
Variable (
me:
menv) (
ve:
venv).
Lemma exp_correct:
forall e c,
sem_exp_instant true R e (
present c) ->
equiv_env (
fun x =>
CE.IsF.Is_free_in_exp x e)
R mems me ve ->
exp_eval me ve (
translate_exp mems e) (
Some c).
Proof.
induction e;
inversion_clear 1;
simpl;
intros;
auto with obcsem.
-
match goal with H:
_ =
_ |-
_ =>
inv H end.
econstructor;
congruence.
-
match goal with H:
_ =
_ |-
_ =>
inv H end.
econstructor;
congruence.
-
unfold tovar.
split_env_assumption;
cases;
try rewrite eq_if_present_present in *;
eauto using exp_eval.
take (
Env.find _ _ =
_)
and rewrite <-
it;
constructor.
-
apply H in H0;
eauto with stcfree.
inv H0;
eauto with obcsem.
-
econstructor;
eauto with obcsem;
now rewrite typeof_correct.
-
econstructor;
eauto with obcsem;
now rewrite 2
typeof_correct.
Qed.
Hint Resolve exp_correct :
obcsem.
Lemma arg_correct:
forall me ve cvars ck e c,
exp_eval me ve (
translate_exp mems e) (
Some c) ->
exp_eval me ve (
translate_arg mems cvars ck e) (
Some c).
Proof.
Hint Resolve arg_correct :
obcsem.
Lemma cexp_correct:
forall e c prog assign me'
ve',
sem_cexp_instant true R e (
present c) ->
equiv_env (
fun x =>
Is_free_in_cexp x e)
R mems me ve ->
(
forall oe,
exp_eval me ve oe (
Some c) ->
stmt_eval prog me ve (
assign oe) (
me',
ve')) ->
stmt_eval prog me ve (
translate_cexp mems assign e) (
me',
ve').
Proof.
Hint Resolve cexp_correct :
obcsem.
Lemma clock_correct_true:
forall types Γ
base ck,
wt_clock types Γ
ck ->
equiv_env (
fun x =>
match x with FunctionalEnvironment.Var x =>
Is_free_in_clock x ck |
_ =>
False end)
R mems me ve ->
sem_clock_instant base (
var_env R)
ck true ->
Is_present_in mems me ve ck.
Proof.
induction ck;
intros *
Wt Equiv Sem;
inv Wt;
inv Sem;
eauto with obcsem.
econstructor;
eauto with obcsem.
-
eapply IHck;
eauto.
intros ????.
eapply Equiv;
eauto.
destruct x;
simpl in *;
auto using Is_free_in_clock.
-
unfold tovar;
split_env_assumption.
cases;
try rewrite eq_if_present_present in *;
eauto with obcsem.
take (
Env.find _ _ =
_)
and rewrite <-
it;
auto with obcsem.
Qed.
Lemma clock_correct_false:
forall types Γ
ck,
wt_clock types Γ
ck ->
equiv_env (
fun x =>
match x with FunctionalEnvironment.Var x =>
Is_free_in_clock x ck |
_ =>
False end)
R mems me ve ->
sem_clock_instant true (
var_env R)
ck false ->
Is_absent_in mems me ve ck.
Proof.
induction ck;
intros *
Wt Equiv Sem;
inv Wt;
inv Sem;
eauto;
[
econstructor 1|
econstructor 2];
eauto.
-
eapply IHck;
eauto.
intros ????.
eapply Equiv;
eauto.
destruct x;
simpl in *;
auto using Is_free_in_clock.
-
eapply clock_correct_true;
eauto.
intros ????.
eapply Equiv;
eauto.
destruct x;
simpl in *;
auto using Is_free_in_clock.
-
unfold tovar;
split_env_assumption.
cases;
try rewrite eq_if_present_present in *;
eauto with obcsem.
take (
Env.find _ _ =
_)
and rewrite <-
it;
auto with obcsem.
Qed.
End ExprClock.
Lemma stmt_eval_Control_fwd:
forall prog types Γ
me ve mems ck s me'
ve',
wt_clock types Γ
ck ->
stmt_eval prog me ve (
Control mems ck s) (
me',
ve') ->
(
Is_present_in mems me ve ck
/\
stmt_eval prog me ve s (
me',
ve'))
\/
(
Is_absent_in mems me ve ck
/\
me' =
me /\
ve' =
ve).
Proof.
intros *
WT StEval.
revert dependent s.
induction WT;
intuition.
simpl in *;
apply IHWT in StEval as [[
Hp Hs]|[
Hp [
Hmenv Henv]]];
intuition;
inv Hs.
take (
nth_error _ _ =
_)
and rewrite nth_error_skip_branches_with in it.
cases;
inv it;
simpl in *;
auto with obcsem.
chase_skip;
eauto with obcsem.
Qed.
Section StmtEvalControl.
Variables (
prog :
program)
(
types :
list type)
(Γ :
list (
ident * (
type *
bool)))
(
insts :
list (
ident *
ident))
(Γ
m :
list (
ident *
type))
(Γ
v :
list (
ident *
type))
(
mems :
PS.t)
(
me :
menv)
(
ve :
venv)
(
ck :
clock)
(
s :
stmt).
Hypotheses (
TypesSpec :
types =
prog.(
Obc.Syn.types))
(
TypeEnvSpec :
type_env_spec Γ Γ
m Γ
v mems)
(
WTmenv :
wt_env (
values me) Γ
m)
(
WTvenv :
wt_env ve Γ
v)
(
WTck :
wt_clock types Γ
ck)
(
WTs :
wt_stmt prog insts Γ
m Γ
v s).
Fact stmt_eval_Control:
(
Is_absent_in mems me ve ck ->
stmt_eval prog me ve (
Control mems ck s) (
me,
ve))
/\
(
forall me'
ve',
Is_present_in mems me ve ck ->
stmt_eval prog me ve s (
me',
ve') ->
stmt_eval prog me ve (
Control mems ck s) (
me',
ve')).
Proof.
If the clock is absent, then the controlled statement evaluates as
a Skip.
Corollary stmt_eval_Control_absent:
Is_absent_in mems me ve ck ->
stmt_eval prog me ve (
Control mems ck s) (
me,
ve).
Proof.
If the clock is present, then the controlled statement evaluates
as the underlying one.
Corollary stmt_eval_Control_present:
forall me'
ve',
Is_present_in mems me ve ck ->
stmt_eval prog me ve s (
me',
ve') ->
stmt_eval prog me ve (
Control mems ck s) (
me',
ve').
Proof.
Variable (
R :
env).
Hypothesis Equiv:
equiv_env (
fun x =>
match x with FunctionalEnvironment.Var x =>
Is_free_in_clock x ck |
_ =>
False end)
R mems me ve.
Corollary stmt_eval_Control_absent':
sem_clock_instant true (
var_env R)
ck false ->
stmt_eval prog me ve (
Control mems ck s) (
me,
ve).
Proof.
Corollary stmt_eval_Control_present':
forall base me'
ve',
sem_clock_instant base (
var_env R)
ck true ->
stmt_eval prog me ve s (
me',
ve') ->
stmt_eval prog me ve (
Control mems ck s) (
me',
ve').
Proof.
End StmtEvalControl.
Reset correctness
Definition add_mems (
mems:
list (
ident * (
const *
type *
clock))) (
me:
menv) :
menv :=
Mem (
fold_left (
fun vs '(
x, (
c,
t,
ck)) =>
Env.add x (
sem_const c)
vs)
mems (
values me))
(
instances me).
Lemma find_inst_add_mems:
forall x me xs,
find_inst x (
add_mems xs me) =
find_inst x me.
Proof.
reflexivity. Qed.
Lemma add_mems_cons:
forall x c t ck xs me,
add_mems ((
x, (
c,
t,
ck)) ::
xs)
me =
add_mems xs (
add_val x (
sem_const c)
me).
Proof.
reflexivity. Qed.
Lemma add_mems_nil:
forall me,
add_mems []
me =
me.
Proof.
destruct me; reflexivity. Qed.
Lemma add_mems_gss:
forall x c t ck xs me,
~
InMembers x xs ->
find_val x (
add_mems ((
x, (
c,
t,
ck)) ::
xs)
me) =
Some (
sem_const c).
Proof.
Lemma find_val_add_mems_in:
forall x c t ck xs me,
NoDupMembers xs ->
In (
x, (
c,
t,
ck))
xs ->
find_val x (
add_mems xs me) =
Some (
sem_const c).
Proof.
intros *
Nodup Hin.
revert me;
induction xs as [|(?,((? & ?)&?))];
intros.
-
inversion Hin.
-
inv Nodup.
destruct Hin as [
E|?].
+
inv E.
now apply add_mems_gss.
+
rewrite add_mems_cons;
auto.
Qed.
Lemma find_val_add_mems_inv:
forall x xs me v,
find_val x (
add_mems xs me) =
Some v ->
(
NoDupMembers xs ->
InMembers x xs ->
exists c t ck,
v =
sem_const c /\
In (
x, (
c,
t,
ck))
xs)
/\
(~
InMembers x xs ->
find_val x me =
Some v).
Proof.
intros *
Find;
split; [
intros *
Nodup Hin|
intros *
Hin].
-
revert dependent me;
induction xs as [|(
x', ((
c,
t),
ck))];
intros;
inv Hin;
inv Nodup.
+
rewrite add_mems_gss in Find;
auto;
inv Find.
exists c,
t,
ck;
intuition.
+
rewrite add_mems_cons in Find.
edestruct IHxs as (?&?&?&?&?);
eauto.
do 3
eexists;
intuition;
eauto;
right;
eauto.
-
revert dependent me;
induction xs as [|(
x', ((
c',
t'),
ck'))];
intros.
+
now rewrite add_mems_nil in Find.
+
rewrite add_mems_cons in Find.
apply NotInMembers_cons in Hin as (? & ?).
apply IHxs in Find;
auto.
rewrite find_val_gso in Find;
auto.
Qed.
Lemma reset_mems_spec:
forall mems prog me ve,
stmt_eval prog me ve (
reset_mems mems) (
add_mems mems me,
ve).
Proof.
Lemma translate_reset_comp:
forall prog me ve s me'
ve',
stmt_eval prog me ve (
translate_reset s) (
me',
ve')
<->
stmt_eval prog me ve (
reset_mems (
s.(
s_lasts) ++
s.(
s_nexts))) (
add_mems (
s.(
s_lasts) ++
s.(
s_nexts))
me,
ve)
/\
stmt_eval prog (
add_mems (
s.(
s_lasts) ++
s.(
s_nexts))
me)
ve (
reset_insts s.(
s_subs)) (
me',
ve').
Proof.
Lemma add_mems_reset_states {
prefs} :
forall (
s: @
system prefs)
me,
reset_states s (
add_mems (
s.(
s_lasts) ++
s.(
s_nexts))
me).
Proof.
Lemma add_mems_state_closed_states:
forall resets me,
state_closed_states (
map fst resets)
me ->
state_closed_states (
map fst resets) (
add_mems resets me).
Proof.
Lemma reset_insts_reset_states {
prefs} :
forall subs prog me ve me'
ve' (
s: @
system prefs),
stmt_eval prog me ve (
reset_insts subs) (
me',
ve') ->
reset_states s me ->
reset_states s me'.
Proof.
Lemma reset_insts_state_closed_states:
forall subs resets prog me ve me'
ve',
stmt_eval prog me ve (
reset_insts subs) (
me',
ve') ->
state_closed_states resets me ->
state_closed_states resets me'.
Proof.
Lemma reset_insts_same_venv:
forall subs prog me ve me'
ve',
stmt_eval prog me ve (
reset_insts subs) (
me',
ve') ->
ve' =
ve.
Proof.
Lemma call_reset_inv:
forall f P s P'
me me'
rvs,
find_system f P =
Some (
s,
P') ->
stmt_call_eval (
translate P)
me f reset []
me'
rvs ->
stmt_eval (
translate P')
me vempty (
translate_reset s) (
me',
vempty)
/\
rvs = [].
Proof.
Lemma call_reset_reset_states:
forall me'
P me f s P',
find_system f P =
Some (
s,
P') ->
stmt_call_eval (
translate P)
me f reset []
me' [] ->
reset_states s me'.
Proof.
Lemma call_reset_state_closed_states:
forall me'
P me f s P',
find_system f P =
Some (
s,
P') ->
stmt_call_eval (
translate P)
me f reset []
me' [] ->
state_closed_states (
map fst (
s.(
s_lasts) ++
s.(
s_nexts)))
me ->
state_closed_states (
map fst (
s.(
s_lasts) ++
s.(
s_nexts)))
me'.
Proof.
Lemma reset_insts_not_InMembers:
forall subs prog me ve me'
ve'
x,
stmt_eval prog me ve (
reset_insts subs) (
me',
ve') ->
~
InMembers x subs ->
find_inst x me' =
find_inst x me.
Proof.
Lemma reset_insts_in:
forall s P P'
me ve me'
ve'
i f g,
find_system f P =
Some (
s,
P') ->
stmt_eval (
translate P')
me ve (
reset_insts s.(
s_subs)) (
me',
ve') ->
In (
i,
g)
s.(
s_subs) ->
find_system g P' <>
None ->
exists me_i,
stmt_call_eval (
translate P') (
match find_inst i me with
|
Some om =>
om
|
None =>
mempty
end)
g reset []
me_i []
/\
find_inst i me' =
Some me_i.
Proof.
Lemma find_inst_reset_insts_inv:
forall subs prog me ve me'
ve'
x me_x,
stmt_eval prog me ve (
reset_insts subs) (
me',
ve') ->
find_inst x me' =
Some me_x ->
InMembers x subs
\/
find_inst x me =
Some me_x.
Proof.
Lemma call_reset_initial_state:
forall me'
P me f s P',
Ordered_systems P ->
find_system f P =
Some (
s,
P') ->
stmt_call_eval (
translate P)
me f reset []
me' [] ->
initial_state P f me' /\ (
state_closed P f me ->
state_closed P f me').
Proof.
Lemma reset_insts_exists {
prefs} :
forall (
s: @
system prefs)
P me ve,
(
forall me'
f s'
P',
find_system f P =
Some (
s',
P') ->
exists me'',
stmt_call_eval (
translate P)
me'
f reset []
me'' []) ->
(
forall i g,
In (
i,
g)
s.(
s_subs) ->
exists s P',
find_system g P =
Some (
s,
P')) ->
exists me',
stmt_eval (
translate (
P))
me ve (
reset_insts s.(
s_subs)) (
me',
ve).
Proof.
unfold reset_insts.
intro;
induction s.(
s_subs)
as [|(
x,
b')];
simpl in *;
intros *
IH Spec;
eauto using stmt_eval.
setoid_rewrite stmt_eval_fold_left_lift.
edestruct Spec as (?&?&
Find);
eauto.
eapply IH in Find as (?&?).
edestruct IHl;
eauto 7.
do 3
eexists;
split;
eauto.
econstructor;
eauto with obcsem.
change ve with (
Env.adds_opt [] []
ve).
econstructor;
eauto.
Qed.
Lemma reset_exists:
forall P f s P'
me,
Ordered_systems P ->
find_system f P =
Some (
s,
P') ->
exists me',
stmt_call_eval (
translate P)
me f reset []
me' [].
Proof.
Theorem reset_spec:
forall P me f s P',
Ordered_systems P ->
find_system f P =
Some (
s,
P') ->
exists me',
stmt_call_eval (
translate P)
me f reset []
me' []
/\
initial_state P f me'
/\ (
state_closed P f me ->
state_closed P f me').
Proof.
Step correctness
Lemma value_to_option_adds_opt:
forall R ve x xs v vs,
In x xs ->
NoDup xs ->
Forall (
fun x =>
Env.find x ve =
None)
xs ->
Forall2 (
sem_var_instant R)
xs vs ->
sem_var_instant R x v ->
Env.find x (
Env.adds_opt xs (
map value_to_option vs)
ve) =
value_to_option v.
Proof.
Lemma eq_if_present_adds_opt:
forall R ve x xs c vs ovs,
In x xs ->
Forall2 (
sem_var_instant R)
xs vs ->
Forall2 eq_if_present vs ovs ->
sem_var_instant R x (
present c) ->
Env.find x (
Env.adds_opt xs ovs ve) =
Some c.
Proof.
induction xs as [|
x'].
now inversion 1.
destruct (
ident_eq_dec x x')
as [
Heq|
Hneq];
intros *
Hin Hvar Hovals Hxsem.
+
subst.
apply Forall2_left_cons in Hvar as (
v &
vs' &
Hyss &
Hvs & ?).
rewrite Hyss in Hovals.
apply Forall2_left_cons in Hovals
as (
ov &
ovals' &
Hovals &
Heqp & ?).
pose proof (
sem_var_instant_det _ _ _ _ Hvs Hxsem)
as Hpvc.
subst;
inv Heqp.
now rewrite Env.find_gsss_opt.
+
pose proof (
Forall2_length _ _ _ Hvar)
as Hlenyss.
pose proof (
Forall2_length _ _ _ Hovals)
as Hlenovals.
destruct vs;
try discriminate.
destruct ovs;
try discriminate.
rewrite Env.find_gsso_opt;
auto.
inv Hin.
now contradiction Hneq.
inv Hvar;
inv Hovals;
eauto.
Qed.
Definition correct_system (
P:
Stc.Syn.program) (
f:
ident) :
Prop :=
forall S xs ys S'
me ins s P',
sem_system P f S xs ys S' ->
find_system f P =
Some (
s,
P') ->
Forall2 eq_if_present xs ins ->
Exists (
fun v =>
v <>
absent)
xs ->
wt_memory S P' (
mems_of_states (
s_lasts s ++
s_nexts s)) (
s_subs s) ->
Forall2 (
fun xt vo =>
wt_option_value vo (
fst (
snd xt))) (
s_in s)
ins ->
me ≋
S ->
exists me',
stmt_call_eval (
translate P)
me f step ins me' (
map value_to_option ys)
/\
me' ≋
S'.
Definition correct_program (
P:
Stc.Syn.program) :
Prop :=
forall f,
correct_system P f.
Lemma noops_exp_exp_eval:
forall isub R mems me ve typs Γ
ty Γ
ck e v xck bck lck,
last_env_spec Γ
ty mems ->
sem_clocked_vars_instant true R Γ
ck ->
equiv_env (
fun x =>
CE.IsF.Is_free_in_exp x e)
R mems me ve ->
noops_exp xck e ->
CE.Typ.wt_exp typs Γ
ty e ->
wc_exp Γ
ck e lck ->
instck bck isub xck =
Some lck ->
sem_clock_instant true (
var_env R)
bck true ->
sem_exp_instant true R e v ->
sem_clock_instant true (
var_env R)
lck false ->
(
forall x,
PS.In x mems ->
find_val x me <>
None) ->
exists v,
exp_eval me ve (
translate_exp mems e)
v.
Proof.
induction e;
simpl;
intros *
Last Hcm EqEnv Hnoo Hwt Hwc Hinst Hbck He Hlck Hmems;
eauto with obcsem.
-
unfold tovar.
destruct (
PS.mem i mems)
eqn:
Himems;
eauto with obcsem.
rewrite PS.mem_spec in Himems.
apply Hmems in Himems.
apply not_None_is_Some in Himems as (
v' &
Hv');
eauto with obcsem.
-
inv Hwt.
take (
In _ Γ
ty)
and apply Last,
Hmems in it.
apply not_None_is_Some in it as (
v' &
Hv');
eauto with obcsem.
-
destruct lck as [|?? []].
now inv Hwc .
destruct xck.
+
inv Hinst.
now apply sem_clock_instant_det with (1:=
Hbck)
in Hlck.
+
simpl in *.
destruct (
instck bck isub xck)
eqn:
Heq;
try discriminate.
destruct (
isub _);
try discriminate.
inv Hwt.
inv Hwc.
inv Hinst.
inv Hlck.
*
now inv He;
eauto with obcsem.
*
inv He;
try match goal with
H:
sem_exp_instant _ _ e (
present _) |-
_ =>
eapply exp_correct in H;
eauto with obcsem end.
match goal with Hle:
sem_exp_instant _ _ e absent,
Hck:
sem_clock_instant _ _ lck true |-
_ =>
apply clock_match_instant_exp_contradiction with (1:=
Hcm) (3:=
Hle)
in Hck;
eauto with obcsem
end.
intuition.
-
destruct xck.
+
inv Hinst.
now apply sem_clock_instant_det with (1:=
Hbck)
in Hlck.
+
inv Hnoo.
-
destruct xck.
+
inv Hinst.
now apply sem_clock_instant_det with (1:=
Hbck)
in Hlck.
+
inv Hnoo.
Qed.
Lemma TcUpdateInst_check_args_translate_arg {
prefs}:
forall (
P: @
Stc.Syn.program prefs)
R mems clkvars me ve Γ
ty Γ
ck i ys ck rst f es ess,
last_env_spec Γ
ty mems ->
(
forall x ck islast,
In (
x, (
ck,
islast)) Γ
ck -> ~
PS.In x mems ->
Env.find x clkvars =
Some ck) ->
sem_clocked_vars_instant true R Γ
ck ->
equiv_env (
fun x =>
CE.IsF.Is_free_in_aexps x ck es)
R mems me ve ->
(
forall x,
PS.In x mems ->
find_val x me <>
None) ->
wt_trconstr P Γ
ty (
TcUpdate ck rst (
UpdInst i ys f es)) ->
wc_trconstr P Γ
ck (
TcUpdate ck rst (
UpdInst i ys f es)) ->
normal_args_tc P (
TcUpdate ck rst (
UpdInst i ys f es)) ->
sem_exps_instant true R es ess ->
sem_clock_instant true (
var_env R)
ck true ->
exists vos,
Forall2 eq_if_present ess vos
/\
Forall2 (
exp_eval me ve) (
map (
translate_arg mems clkvars ck)
es)
vos.
Proof.
intros *
Last Hcvars Hcm EqEnv Himems Hwt Hwc Hnorm Hles Hcksem.
apply Forall2_Forall2_exists,
Forall2_map_2,
Forall2_swap_args.
inversion_clear Hwc as [| | | | |????????
sub Hfind Hwci Hwco].
inversion_clear Hwt as [| | | | |????????
_ _ _ _ Hwte].
inversion_clear Hnorm as [| | | |????????
Hfind'
Hnorm'].
rewrite Hfind in Hfind';
inv Hfind'.
rewrite Forall2_map_1,
Forall2_swap_args in Hnorm'.
apply Forall2_trans_ex with (1:=
Hnorm'),
Forall2_same in Hwci.
clear Hwco Hfind Hnorm'.
apply Forall2_impl_In with (2:=
Hles).
intros le v Hlein Hvin Hsem.
apply Forall_forall with (2:=
Hlein)
in Hwci
as ((
x, (
xty,
xck)) &
Hin &
Hnorm &
Hsubv & (
lck &
WClck &
Hinst)).
simpl_Forall.
assert (
WClck':=
WClck).
assert (
equiv_env (
fun x =>
CE.IsF.Is_free_in_exp x le)
R mems me ve)
by (
weaken_equiv_env with constructor;
apply Exists_exists;
eauto).
eapply clock_match_instant_exp in WClck'
as [(
Hsem' &
Hcksem')|((
c &
Hsem') &
Hcksem')];
eauto;
apply sem_exp_instant_det with (1:=
Hsem)
in Hsem';
subst v.
-
eapply noops_exp_exp_eval in Hnorm as (
v' &
Hv');
eauto.
simpl;
exists v';
eauto.
split;
destruct le;
eauto with obcsem.
destruct xck.
+
inv Hinst.
now apply sem_clock_instant_det with (1:=
Hcksem)
in Hcksem'.
+
simpl in Hinst.
destruct (
instck ck sub xck)
eqn:
Hck;
try discriminate.
match goal with H:
context [
sub ?
i] |-
_ =>
destruct (
sub i)
eqn:
Hisub;
try discriminate end.
injection Hinst;
intro;
subst lck.
inversion_clear WClck as [| |????
Hicks| | | |].
simpl in Hv';
destruct (
PS.mem i0 mems)
eqn:
E.
*
unfold translate_arg,
var_on_base_clock;
simpl;
rewrite E;
simpl;
auto.
*{
apply Hcvars in Hicks.
-
unfold translate_arg,
var_on_base_clock;
simpl;
rewrite Hicks,
E;
simpl.
now rewrite instck_subclock_not_clock_eq with (1:=
Hck).
-
apply PSE.MP.Dec.F.not_mem_iff;
auto.
}
-
exists (
Some c);
simpl;
split;
eauto using arg_correct,
exp_correct with obcsem.
Qed.
Lemma stmt_eval_translate_cexp_venv_inv1:
forall prog me ve mems x me'
ve'
e,
stmt_eval prog me ve (
translate_cexp mems (
Assign x)
e) (
me',
ve') ->
exists c,
ve' =
Env.add x c ve.
Proof.
Lemma stmt_eval_translate_cexp_venv_inv2:
forall prog me ve mems x islast me'
ve'
e,
stmt_eval prog me ve (
translate_cexp mems (
fun e =>
AssignSt x e islast)
e) (
me',
ve') ->
ve' =
ve.
Proof.
Lemma not_Is_variable_in_tc_stmt_eval_venv_inv:
forall tc x P Γ
me ve mems clkvars me'
ve',
wt_trconstr P Γ
tc ->
~
Is_variable_in_tc x tc ->
stmt_eval (
translate P)
me ve (
translate_tc mems clkvars tc) (
me',
ve') ->
Env.find x ve' =
Env.find x ve.
Proof.
intros *
WT Hnd Heval.
destruct tc;
simpl in Heval;
inv WT;
try (
take (
wt_rhs _ _ _ _)
and inv it);
try (
take (
wt_const _ _ _)
and inv it);
eapply stmt_eval_Control_fwd in Heval;
eauto;
destruct Heval as [[
Hipi Heval]|[
Habs [
Hmenv Henv]]];
subst;
auto.
-
inv Heval.
rewrite Env.gso;
auto.
intro;
subst;
apply Hnd;
constructor.
-
apply stmt_eval_translate_cexp_venv_inv1 in Heval as (?&?);
subst.
rewrite Env.gso;
auto.
intro;
subst;
apply Hnd;
constructor.
-
inv Heval;
auto.
-
inv Heval;
auto.
-
inv Heval;
auto.
-
apply stmt_eval_translate_cexp_venv_inv2 in Heval;
subst;
auto.
-
inv Heval;
auto.
-
inv Heval.
rewrite Env.find_In_gsso_opt;
auto.
intro;
apply Hnd;
constructor;
auto.
Qed.
Corollary not_Is_variable_in_stmt_eval_venv_inv:
forall tcs x P Γ
me ve mems clkvars me'
ve',
Forall (
wt_trconstr P Γ)
tcs ->
~
Is_variable_in x tcs ->
stmt_eval (
translate P)
me ve (
translate_tcs mems clkvars tcs) (
me',
ve') ->
Env.find x ve' =
Env.find x ve.
Proof.
Section Trconstr.
Variables (Γ :
list (
ident * (
type *
bool)))
(Γ
v' :
list (
ident *
type))
(Γ
m' :
list (
ident *
type))
(
mems :
PS.t).
Hypothesis (
TypeEnvSpec :
type_env_spec Γ Γ
m' Γ
v'
mems).
Hypothesis (
LastEnvSpec :
last_env_spec Γ
mems).
Lemma trconstr_cons_correct:
forall tc tcs P R S I S'
inputs nexts Ω
clkvars insts me ve,
correct_program P ->
Stc.Typ.wt_program P ->
sem_trconstr P true R S I S'
tc ->
Forall (
sem_trconstr P true R S I S')
tcs ->
wc_trconstr P Ω
tc ->
wt_trconstr P Γ
tc ->
trconstr_mems_spec mems tc ->
trconstr_insts_spec insts tc ->
normal_args_tc P tc ->
Ordered_systems P ->
Is_well_sch inputs nexts (
tc ::
tcs) ->
NoDup (
inputs ++
variables (
tc ::
tcs)) ->
NoDupMembers (
Syn.insts_of (
tc ::
tcs)) ->
last_consistency (
tc ::
tcs) ->
next_consistency (
tc ::
tcs) ->
inst_consistency (
tc ::
tcs) ->
last_reset_clocks_have_sem true (
var_env R) (
tc ::
tcs) ->
next_reset_clocks_have_sem true (
var_env R) (
tc ::
tcs) ->
inst_reset_clocks_have_sem true (
var_env R) (
tc ::
tcs) ->
(
forall i f Si,
In (
i,
f) (
inst_resets_of (
tc ::
tcs)) ->
find_inst i S =
Some Si ->
state_closed P f Si) ->
(
forall i f Ii,
In (
i,
f) (
inst_resets_of (
tc ::
tcs)) ->
find_inst i I =
Some Ii ->
state_closed P f Ii) ->
Memory_Corres R true tcs S I S'
me ->
equiv_env (
fun x =>
Is_free_in_tc x tc)
R mems me ve ->
wt_memory me (
translate P) Γ
m'
insts ->
wt_memory S P Γ
m'
insts ->
wt_env ve Γ
v' ->
sem_clocked_vars_instant true R Ω ->
(
forall x ck islast,
In (
x, (
ck,
islast)) Ω -> ~
PS.In x mems ->
Env.find x clkvars =
Some ck) ->
(
forall x,
PS.In x mems ->
find_val x me <>
None) ->
(
forall x, ~
In x inputs -> ~
Is_variable_in x tcs ->
Env.find x ve =
None) ->
exists me'
ve',
stmt_eval (
translate P)
me ve (
translate_tc mems clkvars tc) (
me',
ve')
/\
Memory_Corres R true (
tc ::
tcs)
S I S'
me'
/\
forall x v,
Is_variable_in_tc x tc ->
sem_var_instant (
var_env R)
x v ->
Env.find x ve' =
value_to_option v.
Proof.
intros *
IH WTP Sem Sems Hwc Hwt Spec_m Spec_i Hnormal Ord Wsch Vars Calls
LResets NResets IResets LResetCks NResetCks IResetCks
Closed TransClosed Corres Equiv WTmenv WTS WTvenv Hcm Hcvars Hmems Hve.
assert (
NoDup (
variables_tc tc))
by (
rewrite Permutation.Permutation_app_comm in Vars;
simpl in Vars;
do 2
apply NoDup_app_weaken in Vars;
auto).
pose proof Hwt as Hwt';
eapply translate_tc_wt with (
clkvars :=
clkvars)
in Hwt';
eauto.
inversion Sem as [?????????
Hexp Hvar|
??????????
Find Hvar FindI|
???????????
FindI Init|
?????????????
Hexp|
?????????????
Hexp|
???????????????
ClockR Find_I Hexps Hck Hsystem Hvars];
subst;
simpl in *;
inv Hwt;
try (
take (
wt_rhs _ _ _ _)
and inv it);
try (
take (
wt_const _ _ _)
and inv it);
eapply Control_wt_inv in Hwt';
eauto.
-
inv WTmenv;
inv Hexp;
take (
sem_rhs_instant _ _ _ _)
and inv it;
exists me;
eexists;
split.
+
eapply stmt_eval_Control_present';
eauto;
auto with obcsem.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
econstructor;
eauto;
simpl_Forall.
*
rewrite typeof_correct;
auto.
*
eapply exp_correct;
eauto.
eapply equiv_env_map;
eauto.
intros;
repeat constructor;
solve_Exists.
+
split.
*
apply Memory_Corres_Def;
auto.
*
inversion_clear 1;
intros Hvar'.
eapply sem_var_instant_det in Hvar;
eauto;
subst.
inv Hvar';
rewrite Env.gss;
auto.
+
eapply stmt_eval_Control_absent';
eauto.
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F.
+
split.
*
apply Memory_Corres_Def;
auto.
*
inversion_clear 1;
intros Hvar'.
eapply sem_var_instant_det in Hvar;
eauto.
unfold variables in Vars.
subst;
simpl in *;
apply NoDup_app_cons in Vars as (
Hnin & ?).
apply Hve;
auto using Is_variable_in_tc.
intro;
apply Hnin,
in_app;
auto.
rewrite Is_variable_in_variables.
intro;
apply Hnin,
in_app;
auto.
-
inv WTmenv;
inv Hexp;
take (
sem_rhs_instant _ _ _ _)
and inv it;
exists me;
eexists;
split.
+
eapply stmt_eval_Control_present';
eauto;
auto with obcsem.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
eapply cexp_correct;
eauto with obcsem.
intros *
E.
econstructor;
eauto.
+
split.
*
apply Memory_Corres_Def;
auto.
*
inversion_clear 1;
intros Hvar'.
eapply sem_var_instant_det in Hvar;
eauto.
inv Hvar;
rewrite Env.gss;
auto.
+
eapply stmt_eval_Control_absent';
eauto.
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F.
+
split.
*
apply Memory_Corres_Def;
auto.
*
inversion_clear 1;
intros Hvar'.
eapply sem_var_instant_det in Hvar;
eauto.
unfold variables in Vars.
subst;
simpl in *;
apply NoDup_app_cons in Vars as (
Hnin & ?).
apply Hve;
auto using Is_variable_in_tc.
intro;
apply Hnin,
in_app;
auto.
rewrite Is_variable_in_variables.
intro;
apply Hnin,
in_app;
auto.
-
inv WTmenv;
destruct r;
do 2
eexists; (
split; [|
split]);
eauto;
try solve [
inversion 1].
+
eapply stmt_eval_Control_present';
eauto with obcsem.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
intuition.
simpl.
econstructor;
eauto with obcsem.
+
eapply Memory_Corres_Reset_present;
eauto.
eapply Is_well_sch_Reset_Last;
eauto.
eapply Is_well_sch_Reset_Next;
eauto.
+
eapply stmt_eval_Control_absent';
eauto using stmt_eval,
exp_correct.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
+
eapply Memory_Corres_Reset_absent;
eauto.
-
inv WTmenv;
destruct r;
do 2
eexists; (
split; [|
split]);
eauto;
try solve [
inversion 1].
+
eapply stmt_eval_Control_present';
eauto using stmt_eval,
exp_correct.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
intuition.
simpl.
constructor;
eauto with obcsem.
+
eapply Memory_Corres_Reset_present;
eauto.
eapply Is_well_sch_Reset_Last;
eauto.
eapply Is_well_sch_Reset_Next;
eauto.
+
eapply stmt_eval_Control_absent';
eauto using stmt_eval,
exp_correct.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
+
eapply Memory_Corres_Reset_absent;
eauto.
-
inv WTmenv;
destruct r.
+
pose proof Init.
inversion_clear Init as [?????
Find Rst].
edestruct reset_spec as (
me' &?&?&
SpecInit);
eauto.
do 2
eexists;
split; [|
split].
*
eapply stmt_eval_Control_present';
eauto;
auto with obcsem.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x;
auto with stcfree.
inv F. }
econstructor;
eauto.
* {
eapply Memory_Corres_InstReset_present;
eauto.
-
eapply initial_state_det;
eauto.
+
apply SpecInit.
unfold instance_match in *.
destruct (
find_inst i me)
eqn:
E.
*
assert (~
Is_update_inst_in i tcs)
as NStep.
{
inversion_clear Wsch as [|?? (?&?&?&?&?)];
eauto using Is_reset_inst_in_tc. }
assert (
state_corres i S me \/
state_corres i I me)
as Scorres.
{
eapply inst_reset_or_not_reset_dec with (
i:=
i)
in Sems as [
NotReset|
Reset].
-
left.
eapply Corres;
eauto.
-
right.
eapply Corres;
eauto.
}
unfold state_corres in Scorres.
rewrite E in Scorres.
destruct Scorres as [
Scorres|
Scorres];
apply orel_find_inst_Some in Scorres as (?&<-&?).
--
eapply Closed;
simpl;
eauto.
--
eapply TransClosed;
simpl;
eauto.
*
eapply state_closed_empty;
eauto.
-
eapply Is_well_sch_Reset_Inst;
eauto.
}
*
inversion 1.
+
exists me,
ve;
split;
try eapply stmt_eval_Control_absent';
eauto;
auto with obcsem.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x;
auto with stcfree.
inv F. }
split;
try inversion 1.
eapply Memory_Corres_InstReset_absent;
eauto.
-
inv WTmenv;
inv Hexp;
eexists;
exists ve;
split.
+
eapply stmt_eval_Control_present';
eauto with obcsem;
eauto with obcsem.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
simpl.
eapply cexp_correct;
eauto with obcsem.
intros;
econstructor;
eauto.
+
split;
try inversion 1.
apply Memory_Corres_Last_present;
auto.
+
eapply stmt_eval_Control_absent';
eauto.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
+
split;
try inversion 1.
eapply Memory_Corres_Last_absent;
auto.
eapply LResetCks.
left;
eauto with stcsyntax.
-
inv WTmenv;
inv Hexp;
eexists;
exists ve;
split.
+
eapply stmt_eval_Control_present';
eauto with obcsem.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
simpl.
econstructor;
eauto using exp_correct with obcsem.
+
split;
try inversion 1.
apply Memory_Corres_Next_present;
auto.
+
eapply stmt_eval_Control_absent';
eauto.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x0;
auto with stcfree.
inv F. }
+
split;
try inversion 1.
eapply Memory_Corres_Next_absent;
auto.
eapply NResetCks.
left;
eauto with stcsyntax.
-
assert (
Forall (
fun ckr :
clock =>
exists r :
bool,
sem_clock_instant true (
var_env R)
ckr r)
ckrs)
as ClockR1.
{
eapply IResetCks.
left;
eauto with stcsyntax. }
destruct (
clock_of_instant xs)
eqn:
E.
+
assert (
Exists (
fun v =>
v <>
absent)
xs)
by (
apply clock_of_instant_true;
auto).
assert (
exists vos,
Forall2 eq_if_present xs vos
/\
Forall2 (
exp_eval me ve)
(
map (
translate_arg mems clkvars ck)
es)
vos)
as (
ivals &
Hivals &
Hievals).
{
eapply TcUpdateInst_check_args_translate_arg;
eauto with obcsem stctyping. }
unfold correct_program,
correct_system in IH.
eapply IH in Hsystem as (
me' &?&?);
eauto.
*{
inv WTmenv.
do 2
eexists;
split.
-
eapply stmt_eval_Control_present';
eauto;
auto with obcsem.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x;
auto with stcfree.
inv F. }
econstructor;
eauto.
-
split.
+
eapply Memory_Corres_Step_present;
eauto.
+
inversion_clear 1;
intros Hvar.
simpl in Vars;
apply NoDup_swap in Vars.
eapply value_to_option_adds_opt;
eauto.
apply Forall_forall;
intros y Hin.
assert (~
In y inputs)
by
(
rewrite app_assoc in Vars;
apply NoDup_app_weaken in Vars;
eapply NoDup_app_In;
eauto).
assert (~
Is_variable_in y tcs).
{
rewrite Permutation_swap in Vars;
apply NoDup_app_r in Vars.
rewrite Is_variable_in_variables.
eapply NoDup_app_In;
eauto. }
apply Hve;
auto.
}
*
inv Spec_i.
assert (~
Is_update_inst_in i tcs)
as NotStep.
{
inv Calls.
rewrite inst_in_insts_of;
auto. }
eapply inst_reset_or_not_reset_dec in Sems as [
NotReset|
Reset].
--
pose proof (
conj NotStep NotReset)
as Cor.
eapply Corres in Cor.
assert (
exists Ii',
Ii' ≋
Ii /\
find_inst i S =
Some Ii')
as (? & <- &?).
{
apply orel_find_inst_Some,
ClockR.
eapply Forall_forall;
intros ?
Hin;
eapply NotReset.
eapply IResets in Hin;
eauto. 2:
left;
eauto with stcsyntax.
inv Hin;
auto.
inv H4. }
inversion_clear WTS as [?????
WTinsts].
eapply Forall_forall in WTinsts;
eauto.
inv WTinsts;
try congruence.
match goal with H:
find_inst i S =
_,
H':
find_inst i S =
_ |-
_ =>
rewrite H in H';
inv H'
end.
match goal with H:
find_system _ _ =
_,
H':
find_unit _ _ =
_ |-
_ =>
setoid_rewrite H in H';
inv H'
end;
auto.
--
pose proof (
conj NotStep Reset)
as Cor.
eapply Corres in Cor.
unfold state_corres in Cor.
rewrite Find_I in Cor;
symmetry in Cor.
assert (
exists Ii',
Ii' ≋
Ii /\
find_inst i me =
Some Ii')
as (? & <- &?)
by (
apply orel_find_inst_Some;
auto).
inversion_clear WTmenv as [?????
WTinsts].
eapply Forall_forall in WTinsts;
eauto.
inv WTinsts;
try congruence.
match goal with H:
find_inst i me =
_,
H':
find_inst i me =
_ |-
_ =>
rewrite H in H';
inv H'
end.
take (
find_unit _ _ =
_)
and eapply find_unit_transform_units_backward in it as (?&?&
Find &?&?);
subst.
match goal with H:
find_system _ _ =
_,
H':
find_unit _ _ =
_ |-
_ =>
setoid_rewrite H in H';
inv H'
end;
auto.
pose proof (@
transform_units_wt_memory'
system class _ _ _ _ _ _ _ _)
as Spec.
apply Spec;
auto.
*
inv WTmenv;
eapply pres_sem_expos with (Γ
m := Γ
m')
in Hievals;
eauto.
--
take (
Forall2 _ _ (
s_in _))
and rename it into Eexps.
apply Forall2_map_1,
Forall2_swap_args in Hievals.
apply Forall2_trans_ex with (2 :=
Eexps),
Forall2_swap_args in Hievals.
simpl_Forall;
subst.
take (
wt_option_value _ _)
and now rewrite typeof_arg_correct in it.
--
take (
Forall _ es)
and rename it into WTexps.
apply Forall_map,
Forall_forall;
intros *
Hin.
eapply Forall_forall in WTexps;
eauto.
assert (
Stc.Syn.types P =
types (
translate P))
by auto.
eapply translate_arg_wt in WTexps;
eauto.
*{
inv WTmenv;
unfold instance_match.
assert (~
Is_update_inst_in i tcs)
as NStep.
{
rewrite insts_of_In, <-
fst_InMembers.
simpl in Calls.
inv Calls;
auto. }
assert (
Inst_with_reset_in i ckrs (
TcUpdate ck ckrs (
UpdInst i ys f es) ::
tcs))
as SpecStep by (
left;
constructor).
apply IResets in SpecStep.
apply reset_or_not_reset_dec'
in ClockR1 as [
NotReset|
Reset].
-
assert (
state_corres i S me)
as Corres'.
+
eapply Corres;
split;
eauto.
intros ?
Res.
eapply Forall_forall in NotReset; [
eauto|].
rewrite SpecStep.
right;
auto.
+
unfold state_corres in Corres'.
rewrite ClockR in Corres';
auto.
inv Corres';
symmetry;
auto.
-
assert (
state_corres i I me)
as Corres'.
+
eapply Corres;
split;
eauto.
eapply Exists_exists in Reset as (?&
Hin&?).
rewrite SpecStep in Hin.
inv Hin.
inv H7.
eauto.
+
unfold state_corres in Corres'.
rewrite Find_I in Corres';
auto.
inv Corres';
symmetry;
auto.
}
+
inv WTmenv.
assert (
absent_list xs)
by (
apply clock_of_instant_false;
auto).
apply sem_system_absent in Hsystem as (? & ?);
auto.
exists me,
ve;
split;
try eapply stmt_eval_Control_absent';
eauto;
auto with obcsem.
1:{
eapply equiv_env_map; [|
eauto].
intros *
F.
destruct x;
auto with stcfree.
inv F. }
split;
eauto using Memory_Corres_Step_absent.
inversion_clear 1;
intros Hvar.
eapply Forall2_in_left in Hvars as (
v' &
Hin &?);
eauto.
eapply sem_var_instant_det in Hvar;
eauto;
subst v'.
eapply Forall_forall in Hin;
eauto.
simpl in Hin;
subst;
simpl.
unfold variables in Vars.
simpl in *.
apply Hve;
auto using Is_defined_in_tc.
*
eapply NoDup_swap,
NoDup_app_In in Vars;
eauto.
intro;
apply Vars,
in_app;
auto.
*
apply NoDup_app_r in Vars.
rewrite Is_variable_in_variables.
eapply NoDup_app_In;
eauto.
Qed.
Hypotheses (
Hndupm :
NoDupMembers Γ
m')
(
Hndupv :
NoDupMembers Γ
v').
Lemma trconstrs_app_correct:
forall tcs'
tcs P R S I S'
inputs nexts Ω
clkvars insts me ve,
let alltcs :=
tcs ++
tcs'
in
correct_program P ->
NoDup (
inputs ++
variables alltcs ++
map fst (
lasts_of alltcs) ++
map fst (
nexts_of alltcs)) ->
NoDupMembers (
Syn.insts_of alltcs) ->
NoDupMembers insts ->
Stc.Typ.wt_program P ->
Forall (
sem_trconstr P true R S I S')
alltcs ->
Forall (
wc_trconstr P Ω)
alltcs ->
Forall (
wt_trconstr P Γ)
alltcs ->
Forall (
trconstr_mems_spec mems)
alltcs ->
Forall (
trconstr_insts_spec insts)
alltcs ->
Forall (
normal_args_tc P)
alltcs ->
sem_clocked_vars_instant true R Ω ->
(
forall x ck islast,
In (
x, (
ck,
islast)) Ω -> ~
PS.In x mems ->
Env.find x clkvars =
Some ck) ->
(
forall x,
PS.In x mems ->
find_val x me <>
None) ->
Ordered_systems P ->
Is_well_sch inputs nexts alltcs ->
last_consistency alltcs ->
next_consistency alltcs ->
inst_consistency alltcs ->
last_reset_clocks_have_sem true (
var_env R)
alltcs ->
next_reset_clocks_have_sem true (
var_env R)
alltcs ->
inst_reset_clocks_have_sem true (
var_env R)
alltcs ->
(
forall i f Si,
In (
i,
f) (
inst_resets_of alltcs) ->
find_inst i S =
Some Si ->
state_closed P f Si) ->
(
forall i f Ii,
In (
i,
f) (
inst_resets_of alltcs) ->
find_inst i I =
Some Ii ->
state_closed P f Ii) ->
(
forall x,
PS.In x mems <->
Is_update_last_in x alltcs \/
Is_update_next_in x alltcs) ->
(
forall x ck,
In (
x, (
ck,
true)) Ω ->
Is_update_last_in x alltcs) ->
(
forall x,
In x nexts <->
Is_update_next_in x alltcs) ->
(
forall x c,
In x inputs ->
sem_var_instant R (
FunctionalEnvironment.Var x) (
present c) ->
Env.find x ve =
Some c) ->
(
forall x,
Env.find x ve <>
None ->
In x inputs) ->
wt_memory me (
translate P) Γ
m'
insts ->
wt_env ve Γ
v' ->
me ≋
S ->
exists me'
ve',
stmt_eval (
translate P)
me ve (
translate_tcs mems clkvars tcs') (
me',
ve')
/\
Memory_Corres R true tcs'
S I S'
me'
/\
forall x v,
Is_variable_in x tcs' ->
sem_var_instant R (
FunctionalEnvironment.Var x)
v ->
Env.find x ve' =
value_to_option v.
Proof.
induction tcs'
as [|
tc];
simpl;
intros *
Corr Vars Insts Hndupi
WT Htcs Hwc Hwt Spec_m Spec_i Hnormal Hcm Hcvars Hmems Ord Wsch
LResets NResets IResets LResetCks NResetCks IResetCks
Closed TransClosed SpecMem SpecLast SpecNext EquivInput EquivInput'
WTm WTe Corres.
-
exists me,
ve.
split;
eauto using stmt_eval;
split;
auto.
+
now apply Memory_Corres_empty_equal_memory.
+
inversion 1.
-
pose proof Wsch as Wsch';
apply Forall'
_app_r in Wsch'.
pose proof Insts as Insts';
rewrite Syn.insts_of_app in Insts'.
rewrite Permutation.Permutation_app_comm in Insts';
apply NoDupMembers_app_l in Insts'.
pose proof Vars as Vars'.
pose proof LResets as LResets';
eapply last_consistency_app in LResets';
eauto.
pose proof NResets as NResets';
eapply next_consistency_app in NResets';
eauto.
pose proof IResets as IResets';
eapply inst_consistency_app in IResets';
eauto.
pose proof LResetCks as LResetCks';
eapply last_reset_clocks_have_sem_app in LResetCks';
eauto.
pose proof NResetCks as NResetCks';
eapply next_reset_clocks_have_sem_app in NResetCks';
eauto.
pose proof IResetCks as IResetCks';
eapply inst_reset_clocks_have_sem_app in IResetCks';
eauto.
pose proof Htcs as Htcs';
apply Forall_app_weaken in Htcs';
inv Htcs'.
pose proof Hwc as Hwc';
apply Forall_app_weaken in Hwc';
inv Hwc'.
pose proof Hwt as Hwt';
apply Forall_app_weaken in Hwt';
inv Hwt'.
pose proof Spec_m as Spec_m';
apply Forall_app_weaken in Spec_m';
inv Spec_m'.
pose proof Spec_i as Spec_i';
apply Forall_app_weaken in Spec_i';
inv Spec_i'.
pose proof Hnormal as Hnormal';
apply Forall_app_weaken in Hnormal';
inv Hnormal'.
rewrite List_shift_first in Vars,
Insts,
Wsch,
NResets,
LResets,
IResets,
LResetCks,
NResetCks,
IResetCks,
Htcs,
SpecMem,
SpecLast,
SpecNext,
Closed,
TransClosed,
Hwc,
Hwt,
Spec_m,
Spec_i,
Hnormal.
edestruct IHtcs'
with (
insts:=
insts)
as (
me' &
ve' &?&?&
Env);
eauto.
take (
stmt_eval _ _ _ _ _)
and pose proof it as StmtEval.
eapply pres_sem_stmt with (
mems := Γ
m') (
insts :=
insts) (Γ
v := Γ
v')
in StmtEval as (
WTmem & ?);
eauto.
+
edestruct trconstr_cons_correct with (
ve :=
ve') (
me :=
me')
as (
me'' &
ve'' &?&?&?);
eauto.
*
rewrite app_assoc,
variables_app in Vars'.
apply NoDup_app_l in Vars'.
rewrite NoDup_swap in Vars';
eauto using NoDup_app_r.
*
intros;
eapply Closed;
eauto.
rewrite <-
List_shift_first,
inst_resets_of_app,
in_app;
auto.
*
intros;
eapply TransClosed;
eauto.
rewrite <-
List_shift_first,
inst_resets_of_app,
in_app;
auto.
*
intros x v Free Hvar.
inversion Wsch'
as [|?? (
FreeSpec&
LastSpec&
NextSpec&
ResetSpec&
_)];
subst;
clear Wsch'.
cases_eqn E;
subst.
eapply SpecMem in E0 as UpdNext.
destruct UpdNext as [
Upd|
Next].
{
destruct v;
simpl;
auto.
eapply PSF.mem_2 in E0;
eauto with obcsem.
assert (
value_corres x0 S'
me')
as <-.
{
eapply H0;
eauto.
left.
eapply FreeSpec in Free as [
Def|[
Inp|
Next]]; [
apply Is_defined_Is_variable_Is_last_in in Def as [
Var|]| |];
auto.
1,2:
exfalso.
-
eapply NoDup_app_r,
NoDup_app_In in Vars.
+
eapply Vars,
in_app_iff,
or_introl,
lasts_of_In;
eauto.
+
apply Is_variable_in_variables,
Exists_app;
auto.
-
eapply NoDup_app_In in Vars;
eauto.
apply Vars.
rewrite 2
in_app_iff.
right;
left.
apply lasts_of_In;
auto.
-
exfalso.
apply SpecNext,
nexts_of_In in Next.
apply lasts_of_In in Upd.
eapply NoDup_app_r,
NoDup_app_r,
NoDup_app_In in Vars;
eauto.
}
eapply Exists_exists in Upd as (?&
Hin&
Upd);
inv Upd.
simpl_Forall.
inversion_clear Htcs as [| | |???????????
FindS FindI Exp L V FindS'| |].
rewrite FindS'.
eapply sem_var_instant_det in Hvar;
eauto;
subst.
constructor.
}
{
eapply Exists_exists in Next as (?&
Hin&
Next);
inv Next.
assert (
Next_with_reset_in x0 ckrs ((
tcs ++ [
tc]) ++
tcs'))
as NextReset''.
{
eapply Exists_exists.
eexists;
split;
eauto with stcsyntax. }
apply NResets in NextReset''.
assert (~
Is_update_last_in x0 tcs')
as NUpd.
{
intros Upd.
eapply NoDup_app_r,
NoDup_app_r,
NoDup_app_In in Vars.
-
eapply Vars,
nexts_of_In,
Exists_exists;
do 2
esplit;
eauto.
constructor.
-
apply lasts_of_In,
Exists_app;
auto.
}
eapply state_reset_or_not_reset_dec with (
x:=
x0)
in H2 as [
NotReset|
Reset].
-
assert (
value_corres x0 S me')
as <-.
{
eapply H0;
split; [|
split];
eauto. }
simpl_Forall.
inversion_clear Htcs as [| | | |???????????
FindS FindI Exp L FindS'|].
rewrite FindS.
2:{
simpl_Forall.
eapply NotReset.
rewrite NextReset''
in H2.
apply Exists_app'
in H2 as [
Hin'|?];
auto.
exfalso.
eapply Is_well_sch_free_Reset in Free;
eauto. }
eapply sem_var_instant_det in Hvar;
eauto.
destruct v';
subst;
auto with obcsem.
-
assert (
value_corres x0 I me')
as <-.
{
eapply H0;
split; [|
split];
eauto. }
simpl_Forall.
inversion_clear Htcs as [| | | |???????????
FindS FindI Exp L FindS'|].
rewrite FindI.
eapply sem_var_instant_det in Hvar;
eauto.
destruct v';
subst;
auto with obcsem.
}
{
apply FreeSpec in Free as [
Def|[
Input|
Next]]; [
apply Is_defined_Is_variable_Is_last_in in Def as [
Def|
Upd]| |].
-
eapply Env in Def;
eauto.
destruct v;
simpl;
auto with obcsem.
rewrite Def;
simpl;
auto with obcsem.
-
exfalso.
eapply PSF.not_mem_iff in E0.
eapply E0,
SpecMem.
left.
apply Exists_app;
auto.
-
assert (~
Is_variable_in x0 tcs').
{
rewrite Is_variable_in_variables.
eapply NoDup_app_In in Vars;
eauto.
contradict Vars.
rewrite variables_app, ?
in_app_iff.
auto. }
erewrite not_Is_variable_in_stmt_eval_venv_inv;
eauto.
destruct v;
auto with obcsem.
eapply EquivInput in Input;
eauto.
rewrite Input;
constructor.
-
exfalso.
eapply PSF.not_mem_iff in E0.
eapply SpecNext,
or_intror,
SpecMem in Next;
eauto.
}
{
assert (
Is_update_last_in x0 ((
tcs ++ [
tc]) ++
tcs'))
as Upd.
{
simpl_Forall.
eapply Is_free_last_wc_trconstr in Free as (?&
InCk);
eauto. }
eapply Exists_exists in Upd as (?&
Hin&
Upd);
inv Upd.
assert (
Last_with_reset_in x0 ckrs ((
tcs ++ [
tc]) ++
tcs'))
as LastReset''.
{
eapply Exists_exists.
eexists;
split;
eauto with stcsyntax. }
apply LResets in LastReset''.
assert (~
Is_update_next_in x0 tcs')
as NUpd.
{
intros Upd.
eapply NoDup_app_r,
NoDup_app_r,
NoDup_app_In in Vars.
-
eapply Vars,
nexts_of_In,
Exists_app;
eauto.
-
apply lasts_of_In,
Exists_exists;
do 2
esplit;
eauto.
constructor.
}
eapply state_reset_or_not_reset_dec with (
x:=
x0)
in H2 as [
NotReset|
Reset].
-
assert (
value_corres x0 S me')
as <-.
{
eapply H0;
split; [|
split];
eauto. }
simpl_Forall.
inversion_clear Htcs as [| | |???????????
FindS FindI Exp L V FindS'| |].
rewrite FindS.
2:{
simpl_Forall.
eapply NotReset.
rewrite LastReset''
in H2.
apply Exists_app'
in H2 as [
Hin'|?];
auto.
exfalso.
eapply Is_well_sch_free_ResetLast in Free;
eauto. }
eapply sem_var_instant_det in Hvar;
eauto.
destruct v';
subst;
auto with obcsem.
-
assert (
value_corres x0 I me')
as <-.
{
eapply H0;
split; [|
split];
eauto. }
simpl_Forall.
inversion_clear Htcs as [| | |???????????
FindS FindI Exp L V FindS'| |].
rewrite FindI.
eapply sem_var_instant_det in Hvar;
eauto.
destruct v';
subst;
auto with obcsem.
}
*
rewrite <-
Corres.
apply transform_units_wt_memory;
auto.
*
intros;
eapply stmt_eval_find_val_mono;
eauto.
*
intros *
Hnin ?;
erewrite not_Is_variable_in_stmt_eval_venv_inv;
eauto.
apply not_Some_is_None;
intros *
E.
apply Hnin,
EquivInput',
not_None_is_Some;
eauto.
*
exists me'',
ve'';
split; [|
split];
auto.
--
unfold translate_tcs;
simpl.
rewrite stmt_eval_fold_left_shift;
setoid_rewrite stmt_eval_eq_Comp_Skip2;
eauto.
--
intros x v IsVar Hvar.
destruct (
Is_variable_in_tc_dec x tc)
as [|
Nvar];
auto.
erewrite not_Is_variable_in_tc_stmt_eval_venv_inv;
eauto.
inv IsVar;
auto.
contradiction.
+
now apply translate_wt.
+
eapply translate_tcs_wt;
eauto.
unfold variables in *;
simpl in *.
apply NoDup_app_r,
NoDup_app_l in Vars'.
rewrite flat_map_app in Vars';
simpl in Vars'.
eauto using NoDup_app_r.
Qed.
Corollary trconstrs_correct:
forall tcs P R S I S'
inputs nexts Ω
clkvars insts me ve,
correct_program P ->
NoDup (
inputs ++
variables tcs ++
map fst (
lasts_of tcs) ++
map fst (
nexts_of tcs)) ->
NoDupMembers (
Syn.insts_of tcs) ->
NoDupMembers insts ->
Stc.Typ.wt_program P ->
Forall (
sem_trconstr P true R S I S')
tcs ->
Forall (
wc_trconstr P Ω)
tcs ->
Forall (
wt_trconstr P Γ)
tcs ->
Forall (
trconstr_mems_spec mems)
tcs ->
Forall (
trconstr_insts_spec insts)
tcs ->
Forall (
normal_args_tc P)
tcs ->
sem_clocked_vars_instant true R Ω ->
(
forall x ck islast,
In (
x, (
ck,
islast)) Ω -> ~
PS.In x mems ->
Env.find x clkvars =
Some ck) ->
(
forall x,
PS.In x mems ->
find_val x me <>
None) ->
Ordered_systems P ->
(
forall i f Si,
In (
i,
f) (
inst_resets_of tcs) ->
find_inst i S =
Some Si ->
state_closed P f Si) ->
(
forall i f Ii,
In (
i,
f) (
inst_resets_of tcs) ->
find_inst i I =
Some Ii ->
state_closed P f Ii) ->
Is_well_sch inputs nexts tcs ->
last_consistency tcs ->
next_consistency tcs ->
inst_consistency tcs ->
last_reset_clocks_have_sem true (
var_env R)
tcs ->
next_reset_clocks_have_sem true (
var_env R)
tcs ->
inst_reset_clocks_have_sem true (
var_env R)
tcs ->
(
forall x,
PS.In x mems <->
Is_update_last_in x tcs \/
Is_update_next_in x tcs) ->
(
forall x ck,
In (
x, (
ck,
true)) Ω ->
Is_update_last_in x tcs) ->
(
forall x,
In x nexts <->
Is_update_next_in x tcs) ->
(
forall x c,
In x inputs ->
sem_var_instant R (
FunctionalEnvironment.Var x) (
present c) ->
Env.find x ve =
Some c) ->
(
forall x,
Env.find x ve <>
None ->
In x inputs) ->
wt_memory me (
translate P) Γ
m'
insts ->
wt_env ve Γ
v' ->
me ≋
S ->
exists me'
ve',
stmt_eval (
translate P)
me ve (
translate_tcs mems clkvars tcs) (
me',
ve')
/\
Memory_Corres R true tcs S I S'
me'
/\
forall x v,
Is_variable_in x tcs ->
sem_var_instant R (
FunctionalEnvironment.Var x)
v ->
Env.find x ve' =
value_to_option v.
Proof.
End Trconstr.
Lemma state_closed_insts_InMembers {
prefs} :
forall (
P: @
Stc.Syn.program prefs)
subs S s Ss,
state_closed_insts P subs S ->
find_inst s S =
Some Ss ->
InMembers s subs.
Proof.
intros *
Closed Sub;
apply Closed in Sub as (?&?&?).
eapply In_InMembers;
eauto.
Qed.
Theorem correctness:
forall P f,
Well_defined P ->
wc_program P ->
Stc.Typ.wt_program P ->
correct_system P f.
Proof.
intros [];
induction systems0 as [|
system];
unfold correct_system;
intros b (
Ord &
WSCH &
NormalArgs)
WC WT ????????
Sem Find Tcs Spec WTS WTins E;
pose proof Sem;
inversion_clear Sem as [?????????
Find' ?
Outs Hscv Htcs Closed TransClosed Closed'];
try now inv Find.
rewrite Find in Find';
inv Find'.
pose proof Find as Find'.
pose proof Ord as Ord'.
inv Ord';
inversion WSCH;
inversion_clear NormalArgs as [|??
Hnormal];
inversion_clear WC as [|??
WCb];
inversion WT as [|?? [
WTb]];
simpl in *;
subst.
assert (
Well_defined (
Stc.Syn.Program types0 externs0 systems0))
by (
split;
auto).
assert (
correct_program (
Stc.Syn.Program types0 externs0 systems0))
by (
unfold correct_program;
intros;
auto).
destruct WCb as (?&?&?&
WCtcs).
destruct WTb as (
WTtcs &?).
eapply find_unit_cons in Find as [[
E'
Find]|[
E'
Find]];
simpl in *;
eauto.
-
inv Find.
assert (
clock_of_instant xs =
true)
as Clock by now apply clock_of_instant_true.
rewrite Clock in Htcs.
assert (~
Is_system_in (
s_name system) (
s_tcs system))
as Notin
by (
eapply find_system_not_Is_system_in with (2 :=
Find');
eauto).
assert (
Forall (
fun oc =>
snd oc <>
s_name system) (
s_subs system)).
{
apply Forall_forall;
intros *
Hin;
apply in_map with (
f :=
snd)
in Hin.
intro E';
rewrite E'
in Hin.
rewrite steps_iresets_of_Is_system_in,
map_app,
in_app_comm,
<-
incl_in_app, <-
s_subs_insts_of in Notin;
try contradiction.
apply incl_map,
s_inst_reset_incl.
}
apply sem_trconstrs_cons in Htcs;
auto.
pose proof (
s_type_env_spec system)
as TypeEnvSpec.
pose proof (
s_trconstr_insts_spec system)
as Spec_i.
edestruct trconstrs_correct
with (1 :=
TypeEnvSpec)
(
me :=
me)
(
ve :=
Env.adds_opt (
map fst (
m_in (
step_method system)))
ins vempty)
(
clkvars :=
Env.adds_with snd system.(
s_out)
(
Env.adds_with snd system.(
s_vars)
(
Env.from_list_with snd system.(
s_in))))
as (
me' &
ve' &?&?&
Equiv);
eauto with stcsyntax stcsem.
+
intros ??
In.
rewrite ps_from_list_In,
map_app,
in_app_iff.
left.
rewrite ?
in_app_iff in In.
destruct In as [|[|]];
solve_In.
+
rewrite fst_NoDupMembers,
map_map, <-
fst_NoDupMembers.
apply s_nodup_lasts_nexts.
+
rewrite <- ?
idfst_app,
NoDupMembers_idfst.
apply s_nodup_vars.
+
rewrite <-
s_lasts_in_tcs, <-
s_nexts_in_tcs, <-
s_vars_out_in_tcs, ?
mems_of_states_fst, <- ?
app_assoc.
apply s_nodup.
+
rewrite <-
s_subs_insts_of.
apply s_nodup_subs.
+
apply s_nodup_subs.
+
apply s_trconstr_mems_spec.
+
apply Forall_forall.
intros (
y, (
ck,
islast))
Hxin.
simpl_app.
apply in_app in Hxin as [
Hxin|
Hxin].
*
rewrite <-
Clock;
eapply Forall_forall in Hscv;
eauto.
auto.
*
eapply sem_clocked_var_instant_tcs in Htcs;
eauto.
--
rewrite fst_NoDupMembers, ?
map_app, ?
map_map.
erewrite 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 using s_nodup.
all:
intros;
destruct_conjs;
auto.
--
rewrite s_defined, <-
s_vars_out_in_tcs, <-
s_lasts_in_tcs, <-
s_nexts_in_tcs, ?
mems_of_states_fst, ?
map_app, ?
map_map, <- ?
app_assoc.
erewrite map_ext with (
l:=
s_vars _),
map_ext with (
l:=
s_out _),
map_ext with (
l:=
s_lasts _),
map_ext with (
l:=
s_nexts _).
reflexivity.
all:
intros;
destruct_conjs;
auto.
+
intros y ??
Hin Hnin.
rewrite ps_from_list_In in Hnin.
pose proof (
s_nodup system)
as Nodup.
rewrite ?
map_app, ?
in_app in Hin.
destruct Hin as [[|[|]]|[|]];
simpl_In.
*
unfold Env.from_list_with.
erewrite 2
Env.gsso_with,
Env.In_find_adds_with;
eauto;
auto.
--
apply fst_NoDupMembers.
eauto using NoDup_app_l.
--
eapply NoDup_app_In in Nodup; [|
solve_In].
contradict Nodup.
rewrite ?
in_app.
left.
solve_In.
--
eapply NoDup_app_In in Nodup; [|
solve_In].
contradict Nodup.
rewrite ?
in_app.
right.
left.
solve_In.
*
erewrite Env.gsso_with,
Env.In_find_adds_with;
eauto;
auto.
--
apply fst_NoDupMembers.
eauto using NoDup_app_l,
NoDup_app_r.
--
eapply NoDup_app_r,
NoDup_app_In in Nodup; [|
solve_In].
contradict Nodup.
rewrite ?
in_app.
left.
solve_In.
*
erewrite Env.In_find_adds_with;
eauto;
auto.
--
apply fst_NoDupMembers.
eauto using NoDup_app_l,
NoDup_app_r.
*
exfalso.
eapply Hnin.
rewrite map_app,
in_app_iff.
left.
solve_In.
*
exfalso.
eapply Hnin.
rewrite map_app,
in_app_iff.
right.
solve_In.
+
setoid_rewrite ps_from_list_In;
intros.
rewrite E;
eapply sem_system_find_val;
eauto.
+
inversion_clear Closed as [?????
Find ?
Insts];
rewrite Find in Find';
inv Find'.
intros ?
b' ?
Hin Sub.
apply Insts in Sub as (
b'' &?&?).
apply s_inst_reset_incl in Hin.
rewrite <-
s_subs_insts_of in Hin.
assert (
b' =
b'')
as ->;
auto.
eapply NoDupMembers_det in Hin;
eauto.
apply s_nodup_subs.
+
inversion_clear TransClosed as [?????
Find ?
Insts];
rewrite Find in Find';
inv Find'.
intros ?
b' ?
Hin Sub.
apply Insts in Sub as (
b'' &?&?).
apply s_inst_reset_incl in Hin.
rewrite <-
s_subs_insts_of in Hin.
assert (
b' =
b'')
as ->;
auto.
eapply NoDupMembers_det in Hin;
eauto.
apply s_nodup_subs.
+
apply s_last_consistency.
+
apply s_next_consistency.
+
apply s_inst_consistency.
+
eapply sem_trconstrs_last_reset_clocks;
eauto using s_last_consistency.
+
eapply sem_trconstrs_next_reset_clocks;
eauto using s_next_consistency.
+
eapply sem_trconstrs_inst_reset_clocks;
eauto using s_inst_consistency.
+
intro.
now rewrite ps_from_list_In,
map_app,
in_app_iff,
s_lasts_in_tcs,
lasts_of_In,
s_nexts_in_tcs,
nexts_of_In.
+
intros *
In.
clear -
In.
rewrite ?
in_app_iff in In.
destruct In as [|[|]];
simpl_In.
rewrite lasts_of_In, <-
s_lasts_in_tcs.
solve_In.
+
intros.
now rewrite nexts_of_In, <-
s_nexts_in_tcs.
+
simpl;
intros;
eapply eq_if_present_adds_opt;
eauto.
1,2:
rewrite map_fst_idfst;
eauto.
unfold sem_var_instant,
var_env in *;
auto.
+
simpl;
rewrite map_fst_idfst;
intros *
Find.
apply not_None_is_Some in Find as (?&
Find);
apply Env.find_adds_opt_spec_Some in Find.
*
rewrite Env.gempty in Find;
destruct Find as [
Hin|];
try discriminate.
eapply in_combine_l;
eauto.
*
transitivity (
length xs);
eapply Forall2_length;
eauto.
+
rewrite E;
simpl in *.
now apply transform_units_wt_memory in WTS.
+
eapply wt_env_adds_opt.
*
rewrite <-2
idfst_app,
NoDupMembers_idfst.
apply s_nodup_vars.
*
apply fst_NoDupMembers,
m_nodupin.
*
apply wt_env_empty.
*
unfold step_method;
simpl.
apply Forall2_map_1,
Forall2_same,
Forall_forall.
intros (
x,
t)
Hin;
simpl.
apply in_app;
auto.
*
unfold idfst;
apply Forall2_swap_args,
Forall2_map_1;
auto.
+
exists me';
split.
*
apply find_unit_transform_units_forward in Find'.
econstructor;
eauto.
--
apply exists_step_method.
--
simpl;
transitivity (
length xs).
++
symmetry;
eapply Forall2_length;
eauto.
++
rewrite length_idfst, <-
map_length with (
f :=
fst);
symmetry;
eapply Forall2_length;
eauto.
--
simpl;
eauto.
--
simpl;
rewrite map_fst_idfst.
clear -
Outs Equiv.
rewrite Forall2_map_2.
eapply Forall2_impl_In;
eauto;
intros.
apply Equiv;
auto.
apply Is_variable_in_variables.
rewrite <-
s_vars_out_in_tcs,
in_app;
auto.
*
inv Closed;
inv Closed';
repeat match goal with
H:
find_system ?
b ?
P =
_,
H':
find_system ?
b ?
P =
_ |-
_ =>
rewrite H in H';
inv H'
end.
{
eapply Memory_Corres_equal_memory;
eauto.
-
intro;
now rewrite map_app,
in_app_iff,
s_lasts_in_tcs,
s_nexts_in_tcs,
lasts_of_In,
nexts_of_In.
-
intros ??
Reset.
rewrite map_app,
s_lasts_in_tcs,
s_nexts_in_tcs, <-
map_app.
apply s_state_reset_incl,
reset_states_of_In;
eauto.
-
intro.
now rewrite fst_InMembers,
s_subs_insts_of,
insts_of_In.
-
intros *
Rst.
eapply insts_of_In,
incl_map.
eapply s_inst_reset_incl.
eapply reset_insts_of_In;
eauto.
}
-
pose proof Ord;
eapply find_unit_other_not_Is_called_in in Ord;
simpl;
eauto;
simpl;
eauto.
apply sem_trconstrs_cons in Htcs;
auto.
+
apply state_closed_other in Closed;
apply state_closed_other in TransClosed;
apply state_closed_other in Closed';
auto.
assert (
Forall (
fun oc =>
snd oc <>
s_name system) (
s_subs s0)).
{
apply Forall_forall;
intros *
Hin;
apply in_map with (
f :=
snd)
in Hin.
intro E'';
rewrite E''
in Hin;
contradiction.
}
edestruct IHsystems0 as (
me' &?&?);
eauto with stcsem.
exists me';
split;
auto.
apply stmt_call_eval_cons;
auto.
+
rewrite steps_iresets_of_Is_system_in,
map_app,
Permutation.Permutation_app_comm, <-
incl_in_app, <-
s_subs_insts_of;
auto.
apply incl_map,
s_inst_reset_incl.
Qed.
Corollary correctness_loop_call:
forall P f s P'
xss yss ins S0,
Well_defined P ->
wc_program P ->
Stc.Typ.wt_program P ->
initial_state P f S0 ->
find_system f P =
Some (
s,
P') ->
wt_memory S0 P' (
mems_of_states (
s_lasts s ++
s_nexts s)) (
s_subs s) ->
(
forall n,
Forall2 (
fun xt vo =>
wt_option_value vo (
fst (
snd xt))) (
s_in s) (
ins n)) ->
loop P f xss yss S0 0 ->
(
forall n,
Forall2 eq_if_present (
xss n) (
ins n)) ->
(
forall n,
Exists (
fun v =>
v <>
absent) (
xss n)) ->
exists me0,
stmt_call_eval (
translate P)
mempty f reset []
me0 []
/\
loop_call (
translate P)
f step ins (
fun n =>
map value_to_option (
yss n)) 0
me0
/\
me0 ≋
S0.
Proof.
intros *
Wdef WC WT Init Find WTS0 WTins Loop Spec Clock.
pose proof Loop as Loop';
inversion_clear Loop'
as [???????
Sem].
inv Sem.
assert (
Ordered_systems P)
as Ord by apply Wdef.
eapply reset_spec with (
me :=
mempty)
in Ord as (
me' &?&?&
Closed);
eauto.
assert (
me' ≋
S0)
as Eq
by (
eapply initial_state_det;
eauto;
eapply Closed,
state_closed_empty;
eauto).
exists me';
split; [|
split];
auto.
clear -
Find Loop Wdef WC WT WTS0 WTins Eq Spec Clock.
revert Loop Eq;
revert dependent S0;
revert me'.
generalize 0.
cofix COFIX;
intros.
inversion_clear Loop as [???????
Sem].
pose proof Wdef;
destruct Wdef as (?&?&?).
edestruct (@
sem_system_wt (
PSP.of_list gensym_prefs));
eauto with typing.
-
clear -
WTins Spec.
specialize (
WTins n);
specialize (
Spec n).
apply Forall2_swap_args in Spec;
apply Forall2_trans_ex with (2 :=
Spec)
in WTins;
clear Spec.
induction WTins as [|???? (?&?&
WT&
E)];
constructor;
auto.
inv E;
simpl;
auto.
-
eapply correctness in Sem as (?&?&?);
eauto.
econstructor;
eauto.
Qed.
End CORRECTNESS.
Module CorrectnessFun
(
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)
(
TransTyp :
STC2OBCTYPING Ids Op OpAux ComTyp Cks Str CE Stc Obc Trans)
<:
CORRECTNESS Ids Op OpAux ComTyp Cks Str CE Stc Obc Trans TransTyp.
Include CORRECTNESS Ids Op OpAux ComTyp Cks Str CE Stc Obc Trans TransTyp.
End CorrectnessFun.