From compcert Require Import common.Errors.
From compcert Require Import common.Behaviors.
From compcert Require Import driver.Compiler.
From Velus Require Import Common.
From Velus Require Import Ident.
From Velus Require Import CoindStreams.
From Velus Require Import ObcToClight.Interface.
From Velus Require Import Instantiator.
From Velus Require Import Lustre.LustreElab.
From Velus Require Import Velus.
From Velus Require Import NLCorrectness.
From Velus Require Import Traces.
From Velus Require Import VelusWorld.
From Velus Require Import VelusCorrectness.
From Velus Require Import Cpo_def Nprod Cpo_streams_type CommonDS.
From Coq Require Import String.
From Coq Require Import List.
Import List.ListNotations.
From Coq Require Import Permutation.
Import Stc.Syn.
Import NL.
Import L.
Import Obc.Syn.
Import Obc.Sem.
Import Obc.Typ.
Import Obc.Equ.
Import Obc.Def.
Import Fusion.
Import Stc2ObcInvariants.
Import IStr.
Import CStr.
Import CIStr.
Import OpAux.
Import Op.
Open Scope error_monad_scope.
Open Scope stream_scope.
Import Common.
Import Restr Den.SdR Den.Sd SDfuns Den.Safe DS_ext.
Import DS_ext.
Import Den.OpErr.
Import Cpo.
Import Cpo_ext.Nprod.
Import Den.SdR.
Import Den.Inf.
The new correctness statements thanks to the denotational semantics
Lemma HasType_In :
forall l x ty,
HasType (
senv_of_ins l)
x ty ->
In (
x,
ty) (
idfst (
idfst l)).
Proof.
Lemma HasClock_In :
forall l x ck,
HasClock (
senv_of_ins l)
x ck ->
In (
x,
ck) (
List.map (
fun '(
x, (_,
ck, _)) => (
x,
ck))
l).
Proof.
intros *
HH;
inv HH.
unfold senv_of_ins in *.
solve_In.
Qed.
Lemma SForall_map :
forall A B P (
f:
A->
B)
xs,
SForall (
fun x =>
P (
f x))
xs <->
SForall P (
Streams.map f xs).
Proof.
conversion from Coq Stream to nprod DS
Section Streams_conversion.
Definition sampl_of_svalue :=
fun (
sv:
svalue) =>
match sv with
|
present v =>
pres v
|
absent =>
abs
end.
Lemma s_vs :
forall s Inf,
S_of_DSv (
DS_of_S (
Streams.map sampl_of_svalue s))
Inf ≡ s.
Proof.
Fixpoint nprod_of_Ss (
l :
list (
Stream svalue)) : @
nprod (
DS (
sampl value)) (
length l) :=
match l with
| [] => 0
|
s ::
tl =>
nprod_cons (
DS_of_S (
Streams.map sampl_of_svalue s))
(
nprod_of_Ss tl)
end.
Lemma nth_nprod_of_Ss :
forall xs k d d',
k <
length xs ->
get_nth k d (
nprod_of_Ss xs) =
DS_of_S (
Streams.map sampl_of_svalue (
nth k xs d')).
Proof.
induction xs as [|? []];
intros *
Hl.
inv Hl.
destruct k;
simpl in *;
try lia;
auto.
destruct k.
-
setoid_rewrite nprod_hd_cons;
auto.
-
simpl in *.
rewrite <- (
IHxs _
d);
auto with arith.
Qed.
Lemma Ss_of_nprod_of_Ss :
forall xs Infxs,
EqSts (
Ss_of_nprod (
nprod_of_Ss xs)
Infxs)
xs.
Proof.
induction xs as [|? []];
intros.
-
constructor.
-
constructor;
auto.
cbn.
now rewrite s_vs.
-
constructor. 2:
apply IHxs.
cbn.
now rewrite s_vs.
Qed.
Lemma nprod_of_Ss_inf :
forall xs,
forall_nprod (@
infinite _) (
nprod_of_Ss xs).
Proof.
induction xs as [|? []];
intros.
-
constructor.
-
apply DS_of_S_inf.
-
constructor.
apply DS_of_S_inf.
apply IHxs.
Qed.
Lemma DSForall_DS_of_S :
forall A (
P:
A->
Prop)
s,
SForall P s ->
DSForall P (
DS_of_S s).
Proof.
cofix Cof;
intros.
destruct s;
inv H.
rewrite DS_inv;
constructor;
eauto.
Qed.
End Streams_conversion.
Properties of streams with only present values
Section PSTR.
Lemma pStr_EqSts :
forall ss1 ss2,
EqSts (
pStr ss1) (
pStr ss2)->
EqSts ss1 ss2.
Proof.
Definition all_pres :
Stream svalue ->
Prop :=
SForall (
fun v =>
match v with absent =>
False |
present _ =>
True end).
Lemma all_pres_pStr :
forall xs,
Forall all_pres (
pStr xs).
Proof.
Lemma clocks_of_pres :
forall xs,
xs <> [] ->
Forall all_pres xs ->
clocks_of xs ≡ Streams.const true.
Proof.
Lemma ac_all_pres :
forall x,
abstract_clock x ≡ Streams.const true <->
all_pres x.
Proof.
Lemma all_pres_pStr1 :
forall xs,
all_pres xs ->
exists ys,
xs ≡ Streams.map present ys.
Proof.
Lemma pStr_all_pres :
forall xs,
Forall all_pres xs ->
exists rs,
EqSts xs (
pStr rs).
Proof.
induction xs;
intros *
Hf.
exists [];
constructor.
inv Hf.
destruct IHxs as (
rs &
Heq);
auto.
destruct (
all_pres_pStr1 _
H1)
as (
ys & ?).
exists (
ys ::
rs).
constructor;
auto.
Qed.
End PSTR.
Correspondance of definitions of valid inputs in the two models.
It could probably work with sampled inputs too.
Lemma wt_wc_wf_inputs :
forall {
PSyn Prefs} (
G : @
global PSyn Prefs),
forall main n ins,
find_node main G =
Some n ->
Forall (
fun '(_, (_,
ck, _)) =>
ck =
Cks.Cbase) (
n_in n) ->
wt_ins G main ins ->
wc_ins G main (
pStr ins) ->
wf_inputs n (
nprod_of_Ss (
pStr ins)).
Proof.
intros *
Hfind Hbase Hwt Hwc.
destruct Hwc as (
H &
n' &?&
Hf1 &
Hf2).
rewrite Hfind in *.
take (
Some _ =
Some _)
and inv it.
assert (
Hl :
length (
pStr ins) =
length (
n_in n')).
{
apply Forall2_length in Hf2.
unfold pStr in *.
repeat rewrite length_map in *;
auto. }
split;
auto.
apply Hwt in Hfind as Hwti.
unfold NLCorrectness.wt_streams in Hwti.
intros x ty ck Hty Hck s;
subst s.
unfold denot_var.
destruct (
mem_ident x _)
eqn:
Hin.
2:{
repeat split;
try apply DSForall_bot.
unfold cl_DS.
unfold AC.
rewrite MAP_map,
map_bot;
auto. }
apply mem_ident_spec in Hin.
apply HasType_ins_app in Hty;
auto using node_NoDupMembers.
apply HasClock_ins_app in Hck;
auto using node_NoDupMembers.
assert (
Hmap :
forall l,
List.map fst (
idfst (
idfst l)) =
idents l).
{
intro;
unfold idfst,
idents.
rewrite 2
map_map;
apply List.map_ext;
auto. }
repeat split.
-
apply HasType_In in Hty.
eapply In_nth with (
d := _)
in Hty as (
k &
Hk &
Hnth);
subst.
apply (
f_equal fst)
in Hnth as Hfnth.
rewrite <-
map_nth in Hfnth;
simpl in Hfnth.
rewrite <-
Hfnth,
Hmap.
eapply CommonList2.Forall2_nth with (
n :=
k)
in Hwti.
rewrite Hnth in Hwti;
simpl in *.
erewrite env_of_np_nth ,
nth_nprod_of_Ss with (
k:=
k);
auto.
unfold pStr.
rewrite map_nth.
apply DSForall_DS_of_S,
SForall_map,
SForall_map;
eauto.
all:
unfold pStr,
idents,
idfst in *;
repeat rewrite length_map in *;
try congruence.
unfold mem_nth.
rewrite CommonList2.mem_nth_nth;
auto using node_NoDup_in.
rewrite length_map;
auto.
-
apply HasClock_In in Hck.
unfold cl_DS.
remember (
env_of_np (
idents (
n_in n')) (
nprod_of_Ss (
pStr ins)))
as env eqn:
HH.
assert (
Henv :
forall x,
In x (
idents (
n_in n')) ->
AC (
env x) ==
DS_const true).
{
subst env.
intros y Hiny.
clear -
Hiny Hl.
eapply In_nth with (
d :=
xH)
in Hiny as (
k &
Hk &
Hnth);
subst.
erewrite env_of_np_nth ,
nth_nprod_of_Ss with (
k:=
k);
auto.
unfold pStr.
rewrite <-
map_nth,
map_map, <- 2
map_nth, 2
map_map.
erewrite nth_indep,
map_nth.
{
remember (
nth k ins _)
eqn:
HH;
clear HH.
clear Hl Hk.
clear n'.
coind_Oeq Cof.
destruct s.
setoid_rewrite DS_inv in HU at 3.
constructor;
intros;
split.
rewrite HU,
HV.
simpl.
rewrite AC_cons,
DS_const_eq, 2
first_cons;
auto.
eapply Cof;
auto.
rewrite HU;
simpl.
rewrite AC_cons,
rem_cons;
auto.
rewrite HV,
DS_const_eq,
rem_cons at 1;
auto.
}
all:
unfold idents,
pStr in *;
repeat rewrite length_map in *;
try congruence.
unfold mem_nth.
rewrite CommonList2.mem_nth_nth;
auto using node_NoDup_in.
rewrite length_map;
auto. }
clear HH;
rewrite Henv;
auto.
assert (
bss (
idents (
n_in n'))
env ==
DS_const true)
as ->.
{
assert ((
idents (
n_in n')) <> [])
as Hn0.
{
unfold idents.
pose proof (
n_ingt0 n').
intro;
subst;
inv H1.
apply map_eq_nil in H3.
rewrite H3 in *;
simpl in *;
lia. }
clear -
Hn0 Henv.
revert Hn0 Henv.
generalize (
idents (
n_in n')).
induction l as [|?[]];
intros;
try congruence.
simpl.
setoid_rewrite Henv;
auto.
constructor;
reflexivity.
rewrite bss_cons,
IHl;
try congruence;
auto.
2:
simpl in *;
eauto.
rewrite Henv. 2:
constructor;
auto.
rewrite zip_const,
MAP_map,
map_DS_const;
auto.
}
apply Oeq_le.
assert (
ck =
Cks.Cbase);
subst;
auto.
clear -
Hbase Hck.
apply in_map_iff in Hck as ((?&[]&?)&?&?).
inv H.
simpl_Forall;
auto.
-
eapply In_nth with (
d :=
xH)
in Hin as (
k &
Hk &
Hnth);
subst.
erewrite env_of_np_nth ,
nth_nprod_of_Ss with (
k:=
k);
auto.
unfold pStr.
rewrite map_nth.
apply DSForall_DS_of_S,
SForall_map,
SForall_map;
simpl;
eauto.
apply SForall_forall;
auto.
all:
unfold idents,
pStr in *;
repeat rewrite length_map in *;
try congruence.
unfold mem_nth.
rewrite CommonList2.mem_nth_nth;
auto using node_NoDup_in.
rewrite length_map;
auto.
Unshelve.
all:
eauto.
all:
try exact (
Streams.const (
Vscalar Values.Vundef)).
exact (
Streams.const absent).
Qed.
Lemma sem_node_outs :
forall (
HasCausInj :
forall (
Γ :
static_env) (
x cx :
ident),
HasCaus Γ x cx ->
cx =
x),
forall {
PSyn Prefs} (
G : @
global PSyn Prefs),
forall f n ins outs,
find_node f G =
Some n ->
Forall all_pres ins ->
Forall (
fun '(_, (_,
ck, _, _)) =>
ck =
Cks.Cbase) (
n_out n) ->
sem_node_ck G f ins outs ->
Forall all_pres outs.
Proof.
Lemma find_node_complete :
forall f G n,
find_node f G =
Some n ->
find_node f (
complete_global G) =
Some (
complete_node n).
Proof.
Lemma wc_ins_complete :
forall G f ins,
wc_ins G f (
pStr ins) ->
wc_ins (
complete_global G)
f (
pStr ins).
Proof.
Local Hint Resolve
wc_global_Ordered_nodes
complete_global_wt complete_global_wc
auto_global_wt auto_global_wc
switch_global_wt switch_global_wc
inlinelocal_global_wt inlinelocal_global_wc inlinelocal_global_sem
unnest_global_wt unnest_global_wc unnest_global_sem
normlast_global_wt normlast_global_wc normlast_global_sem
normfby_global_wt normfby_global_wc normfby_global_sem
check_causality_correct :
core.
Local Ltac unfold_l_to_nl Hltonl :=
unfold l_to_nl in Hltonl;
simpl in Hltonl;
repeat rewrite print_identity in Hltonl;
destruct (
is_causal _)
eqn:
Hcaus;
simpl in Hltonl; [|
inv Hltonl];
repeat rewrite print_identity in Hltonl;
Errors.monadInv Hcaus.
Section Theorems.
Variables
(
D :
list LustreAst.declaration)
(
G : @
global (
fun _ _ =>
True)
elab_prefs)
(
Gp :
wt_global G /\
wc_global G)
(
P :
Asm.program)
(
main :
ident)
(
ins :
list (
Stream value))
(
n : @
node (
fun _ _ =>
True)
elab_prefs).
Hypothesis
(
Restr :
Restr.restr_global G)
(
HasCausInj :
forall Γ x cx,
HasCaus Γ x cx ->
cx =
x)
(
Elab :
elab_declarations D =
OK (
exist _
G Gp))
(
Comp :
lustre_to_asm (
Some main)
G =
OK P)
(
Hwti :
wt_ins G main ins)
(
Hwci :
wc_ins G main (
pStr ins))
(
Hcau :
Forall node_causal (
nodes G))
(
Hfind :
find_node main (
G) =
Some n)
(
Hckin :
Forall (
fun '(_,(_,
ck,_)) =>
ck =
Cks.Cbase) (
n_in n))
(
Hckout :
Forall (
fun '(_,(_,
ck,_,_)) =>
ck =
Cks.Cbase) (
n_out n)).
Theorem behavior_asm_exists :
no_rte_global_main G main (
env_of_np (
List.map fst (
n_in n)) (
nprod_of_Ss (
pStr ins))) ->
exists outs,
Sem.sem_node (
G)
main (
pStr ins) (
pStr outs)
/\
exists T,
program_behaves (
Asm.semantics P) (
Reacts T)
/\
bisim_IO G main ins outs T.
Proof.
We introduce a local notion of streams unicity
Definition unique_sts {
A} (
P :
list (
Stream A)->
Prop) (
x:
list (
Stream A)) :
Prop :=
P x /\
forall (
x':
list (
Stream A)),
P x' ->
EqSts x x'.
Local Disable Notation "'exists' ! x .. y , p".
Local Notation "'exists' ! x .. y , p" :=
(
ex (
unique_sts (
fun x => .. (
ex (
unique_sts (
fun y =>
p))) ..)))
(
at level 200,
x binder,
right associativity).
Corollary behavior_asm_exists_uniq :
no_rte_global_main G main (
env_of_np (
List.map fst (
n_in n)) (
nprod_of_Ss (
pStr ins))) ->
exists !
outs,
Sem.sem_node (
G)
main (
pStr ins) (
pStr outs)
/\
exists T,
program_behaves (
Asm.semantics P) (
Reacts T)
/\
bisim_IO G main ins outs T.
Proof.
Correction with no-run-time-errors check
Corollary behavior_asm_exists_check :
CheckOp.check_global G =
true ->
exists outs,
Sem.sem_node (
G)
main (
pStr ins) (
pStr outs)
/\
exists T,
program_behaves (
Asm.semantics P) (
Reacts T)
/\
bisim_IO G main ins outs T.
Proof.
End Theorems.