From compcert Require Import common.Errors.
From compcert Require Import common.Events.
From compcert Require Import common.Behaviors.
From compcert Require Import common.Determinism.
From compcert Require Import cfrontend.Clight.
From compcert Require Import cfrontend.ClightBigstep.
From compcert Require Import lib.Integers.
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.Generation.
From Velus Require Import ClightToAsm.
From Velus Require Import ObcToClight.Correctness.
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.
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.
From Velus Require Import Traces.
From Velus Require Import VelusWorld.
From Coq Require Import String.
From Coq Require Import List.
Import List.ListNotations.
From Coq Require Import Permutation.
Open Scope error_monad_scope.
Open Scope stream_scope.
Import Common.
Section WtStream.
Context {
PSyn :
list decl ->
block ->
Prop} {
prefs :
PS.t}.
Variable G: @
global PSyn prefs.
Variable main:
ident.
Variable ins:
list (
Stream value).
Variable outs:
list (
Stream value).
Definition wt_ins :=
forall node,
find_node main G =
Some node ->
NLCorrectness.wt_streams ins (
idfst (
idfst node.(
n_in))).
Definition wt_outs :=
forall node,
find_node main G =
Some node ->
NLCorrectness.wt_streams outs (
idfst (
idfst (
idfst node.(
n_out)))).
End WtStream.
Definition wc_ins {
PSyn prefs} (
G: @
global PSyn prefs)
main ins :=
sem_clock_inputs G main ins.
A bisimulation relation between a declared node's trace and a given trace
Inductive bisim_IO {
PSyn prefs} (
G: @
global PSyn prefs) (
f:
ident) (
ins outs:
list (
Stream value)):
traceinf ->
Prop :=
IOStep:
forall T node
(
Len_ins :
Datatypes.length ins =
Datatypes.length node.(
n_in))
(
Len_outs :
Datatypes.length outs =
Datatypes.length node.(
n_out)),
find_node f G =
Some node ->
traceinf_sim T (
trace_node node ins outs Len_ins Len_outs 0) ->
bisim_IO G f ins outs T.
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.
Correctness from Lustre to NLustre
Lemma behavior_l_to_nl:
forall G G' main ins outs,
wt_global G ->
wc_global G ->
Sem.sem_node G main ins outs ->
wc_ins G main ins ->
l_to_nl G =
OK G' ->
CoindSem.sem_node G' main ins outs.
Proof.
Fact l_to_nl_find_node' :
forall G G' f n',
NL.Syn.find_node f G' =
Some n' ->
l_to_nl G =
OK G' ->
exists n,
find_node f G =
Some n /\
NL.Syn.n_in n' =
idfst (
n_in n) /\
NL.Syn.n_out n' =
idfst (
idfst (
n_out n)).
Proof.
intros G *
Hfind Hltonl.
unfold_l_to_nl Hltonl.
eapply TR.Tr.find_node_global' in Hfind as (
n''&
Hfind&
Htonode);
eauto.
eapply global_iface_eq_find in Hfind as (
n&
Hfind&(_&_&
Hin&
Hout));
eauto.
2:{
eapply global_iface_eq_sym.
eapply global_iface_eq_trans,
normfby_global_eq.
eapply global_iface_eq_trans,
normlast_global_iface_eq.
eapply global_iface_eq_trans,
unnest_global_eq.
eapply global_iface_eq_trans,
inlinelocal_global_iface_eq.
eapply global_iface_eq_trans,
switch_global_iface_eq.
apply global_iface_eq_refl. }
apply auto_global_find_node' in Hfind as (?&
Hfind&(_&_&
Hin'&
Hout')).
eapply global_iface_eq_find in Hfind as (?&
Hfind&(_&_&
Hin''&
Hout''));
eauto.
2:{
apply global_iface_eq_sym.
apply complete_global_iface_eq. }
do 2
esplit;
eauto;
split.
-
eapply TR.Tr.to_node_in in Htonode;
eauto.
unfold idfst.
erewrite map_ext, <-
Hin'', <-
Hin', <-
Hin,
map_ext.
symmetry;
apply Htonode.
1,2:
intros;
destruct_conjs;
auto.
-
eapply TR.Tr.to_node_out in Htonode;
eauto.
unfold idfst.
erewrite map_map,
map_ext, <-
Hout'', <-
Hout', <-
Hout,
map_ext, <-
map_map.
symmetry;
apply Htonode.
1,2:
intros;
destruct_conjs;
auto.
Qed.
Simply link the trace of a Lustre node with the trace of an NLustre node with the same parameters
Lemma trace_inf_sim_node {
PSyn} {
prefs}:
forall (
node: @
node PSyn prefs)
ins outs
(
Len_ins:
Datatypes.length ins =
Datatypes.length node.(
n_in))
(
Len_outs:
Datatypes.length outs =
Datatypes.length node.(
n_out))
n n' Spec_in_out_n' Len_ins_n' Len_outs_n',
idfst (
NL.Syn.n_in n') =
idfst (
idfst (
n_in node)) ->
idfst (
NL.Syn.n_out n') =
idfst (
idfst (
idfst (
n_out node))) ->
traceinf_sim (
NLCorrectness.trace_node n' ins outs Spec_in_out_n' Len_ins_n' Len_outs_n' n)
(
trace_node node ins outs Len_ins Len_outs n).
Proof.
The ultimate lemma states that, if
- the parsed declarations D elaborate to a dataflow program G and
a proof Gp that it satisfies wt_global G and wc_global G,
- the values on input streams ins are well-typed according to the
interface of the main node,
- the inputs of the main node are all on the base clock
- the input and output streams are related by the dataflow semantics
of the node main in G, and
- compilation succeeds in generating an assembler program P,
then the assembler program generates an infinite sequence of volatile
reads and writes that correspond to the successive values on the
input and output streams.
Theorem behavior_asm:
forall D G Gp P main ins outs,
elab_declarations D =
OK (
exist _
G Gp) ->
lustre_to_asm (
Some main)
G =
OK P ->
wt_ins G main ins ->
wc_ins G main (
pStr ins) ->
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.
Corollary behavior_asm_trace_node:
forall D G Gp P main ins outs,
elab_declarations D =
OK (
exist _
G Gp) ->
lustre_to_asm (
Some main)
G =
OK P ->
wt_ins G main ins ->
wc_ins G main (
pStr ins) ->
Sem.sem_node G main (
pStr ins) (
pStr outs) ->
exists node Len_ins Len_outs,
find_node main G =
Some node
/\
program_behaves (
Asm.semantics P)
(
Reacts (
trace_node node ins outs Len_ins Len_outs 0)).
Proof.
Corollary behavior_asm_velus_world_trace_node_and_nothing_else:
forall D G Gp P main ins outs,
elab_declarations D =
OK (
exist _
G Gp) ->
lustre_to_asm (
Some main)
G =
OK P ->
wt_ins G main ins ->
wc_ins G main (
pStr ins) ->
Sem.sem_node G main (
pStr ins) (
pStr outs) ->
exists node Len_ins Len_outs,
find_node main G =
Some node
/\
program_behaves (
world_sem (
Asm.semantics P) (
velus_world G main ins))
(
Reacts (
trace_node node ins outs Len_ins Len_outs 0))
/\
forall beh,
program_behaves (
world_sem (
Asm.semantics P) (
velus_world G main ins))
beh
->
same_behaviors beh (
Reacts (
trace_node node ins outs Len_ins Len_outs 0)).
Proof.