From Coq Require Import PArith.
From Coq Require Import List.
Import List.ListNotations.
Open Scope list_scope.
From Velus Require Import Common.
From Velus Require Import CommonProgram.
From Velus Require Import CommonTyping.
From Velus Require Import Operators.
From Velus Require Import Clocks.
From Velus Require Import StaticEnv.
From Velus Require Import Lustre.LSyntax.
Ordering of Lustre nodes
Module Type LORDERED
(
Ids :
IDS)
(
Op :
OPERATORS)
(
OpAux :
OPERATORS_AUX Ids Op)
(
Cks :
CLOCKS Ids Op OpAux)
(
Senv :
STATICENV Ids Op OpAux Cks)
(
Import Syn :
LSYNTAX Ids Op OpAux Cks Senv).
Inductive Is_node_in_exp :
ident ->
exp ->
Prop :=
|
INEunop:
forall f op e a,
Is_node_in_exp f e ->
Is_node_in_exp f (
Eunop op e a)
|
INEbinop:
forall f op e1 e2 a,
Is_node_in_exp f e1 \/
Is_node_in_exp f e2 ->
Is_node_in_exp f (
Ebinop op e1 e2 a)
|
INEextcall:
forall f g es a,
Exists (
Is_node_in_exp f)
es ->
Is_node_in_exp f (
Eextcall g es a)
|
INEfby:
forall f le1 le2 la,
Exists (
Is_node_in_exp f)
le1 \/
Exists (
Is_node_in_exp f)
le2 ->
Is_node_in_exp f (
Efby le1 le2 la)
|
INEarrow:
forall f le1 le2 la,
Exists (
Is_node_in_exp f)
le1 \/
Exists (
Is_node_in_exp f)
le2 ->
Is_node_in_exp f (
Earrow le1 le2 la)
|
INEwhen:
forall f le x b la,
Exists (
Is_node_in_exp f)
le ->
Is_node_in_exp f (
Ewhen le x b la)
|
INEmerge:
forall f x es la,
Exists (
fun es =>
Exists (
Is_node_in_exp f) (
snd es))
es ->
Is_node_in_exp f (
Emerge x es la)
|
INEcase:
forall f e es d la,
Is_node_in_exp f e
\/
Exists (
fun es =>
Exists (
Is_node_in_exp f) (
snd es))
es
\/ (
exists d0,
d =
Some d0 /\
Exists (
Is_node_in_exp f)
d0) ->
Is_node_in_exp f (
Ecase e es d la)
|
INEapp1:
forall f g le ler a,
Exists (
Is_node_in_exp f)
le \/
Exists (
Is_node_in_exp f)
ler ->
Is_node_in_exp f (
Eapp g le ler a)
|
INEapp2:
forall f le ler a,
Is_node_in_exp f (
Eapp f le ler a).
Definition Is_node_in_eq (
f:
ident) (
eq:
equation) :
Prop :=
List.Exists (
Is_node_in_exp f) (
snd eq).
Inductive Is_node_in_scope {
A} (
P_in :
A ->
Prop) (
f :
ident) :
scope A ->
Prop :=
|
INScope :
forall locs blks,
Exists (
fun '(
_, (
_,
_,
_,
o)) =>
LiftO False (
fun '(
e,
_) =>
Is_node_in_exp f e)
o)
locs
\/
P_in blks ->
Is_node_in_scope P_in f (
Scope locs blks).
Inductive Is_node_in_branch {
A} (
P_in :
A ->
Prop) :
branch A ->
Prop :=
|
INBranch :
forall caus blks,
P_in blks ->
Is_node_in_branch P_in (
Branch caus blks).
Inductive Is_node_in_block (
f:
ident) :
block ->
Prop :=
|
INBeq:
forall eq,
Is_node_in_eq f eq ->
Is_node_in_block f (
Beq eq)
|
INBreset :
forall blocks er,
Exists (
Is_node_in_block f)
blocks \/
Is_node_in_exp f er ->
Is_node_in_block f (
Breset blocks er)
|
INBswitch :
forall ec branches,
Is_node_in_exp f ec
\/
Exists (
fun blks =>
Is_node_in_branch (
Exists (
Is_node_in_block f)) (
snd blks))
branches ->
Is_node_in_block f (
Bswitch ec branches)
|
INBlocal :
forall scope,
Is_node_in_scope (
Exists (
Is_node_in_block f))
f scope ->
Is_node_in_block f (
Blocal scope).
Definition Ordered_nodes {
PSyn prefs} : @
global PSyn prefs ->
Prop :=
Ordered_program (
fun f nd =>
Is_node_in_block f nd.(
n_block)).
Properties of Ordered_nodes
Section Ordered_nodes_Properties.
Lemma Ordered_nodes_append {
PSyn prefs}:
forall (
G G': @
global PSyn prefs),
suffix G G'
->
Ordered_nodes G'
->
Ordered_nodes G.
Proof.
Lemma find_node_later_not_Is_node_in {
PSyn prefs}:
forall f types externs (
nd: @
node PSyn prefs)
nds nd',
Ordered_nodes (
Global types externs (
nd::
nds))
->
find_node f (
Global types externs nds) =
Some nd'
-> ~
Is_node_in_block nd.(
n_name)
nd'.(
n_block).
Proof.
Lemma find_node_not_Is_node_in {
PSyn prefs}:
forall f (
nd: @
node PSyn prefs)
G,
Ordered_nodes G
->
find_node f G =
Some nd
-> ~
Is_node_in_block nd.(
n_name)
nd.(
n_block).
Proof.
End Ordered_nodes_Properties.
Actually, any wt or wc program is also ordered :)
We can use the wl predicates + hypothesis that there is no duplication in the node names
Lemma wl_exp_Is_node_in_exp {
PSyn prefs} :
forall (
G: @
global PSyn prefs)
e f,
wl_exp G e ->
Is_node_in_exp f e ->
In f (
map n_name (
nodes G)).
Proof.
intros *
Hwl Hisin.
induction e using exp_ind2;
inv Hwl;
inv Hisin;
repeat match goal with
|
H:
_ \/
_ |-
_ =>
destruct H
|
H:
forall x,
Some _ =
Some x ->
_ |-
_ =>
specialize (
H _ eq_refl)
|
_ =>
simpl_Exists;
simpl_Forall;
subst
end;
auto.
-
assert (
find_node f0 G <>
None)
as Hfind.
{
intro contra.
congruence. }
apply find_node_Exists,
Exists_exists in Hfind as (?&?&?).
solve_In.
Qed.
Lemma wl_equation_Is_node_in_eq {
PSyn prefs} :
forall (
G: @
global PSyn prefs)
eq f,
wl_equation G eq ->
Is_node_in_eq f eq ->
In f (
map n_name (
nodes G)).
Proof.
Lemma wl_block_Is_node_in_block {
PSyn prefs} :
forall (
G: @
global PSyn prefs)
d f,
wl_block G d ->
Is_node_in_block f d ->
In f (
map n_name (
nodes G)).
Proof.
Lemma wl_node_Is_node_in {
PSyn prefs} :
forall (
G: @
global PSyn prefs)
n f,
wl_node G n ->
Is_node_in_block f (
n_block n) ->
In f (
map n_name (
nodes G)).
Proof.
Lemma wl_global_Ordered_nodes {
PSyn prefs} :
forall (
G: @
global PSyn prefs),
wl_global G ->
Ordered_nodes G.
Proof.
Lemma Ordered_nodes_change_types {
PSyn prefs} :
forall (
nds :
list (@
node PSyn prefs))
enms1 enms2 externs1 externs2,
Ordered_nodes (
Global enms1 externs1 nds) ->
Ordered_nodes (
Global enms2 externs2 nds).
Proof.
induction nds;
intros *
Hord;
inv Hord;
constructor;
simpl in *.
-
destruct H1 as (
Hnin&
Hnames).
split;
auto.
intros *
Hinblk.
specialize (
Hnin _ Hinblk)
as (?&?&?&?).
split;
auto.
destruct (
find_unit f {|
types :=
enms2;
nodes :=
nds |})
as [(?&?)|]
eqn:
Hnone;
eauto.
exfalso.
apply find_unit_None in Hnone.
simpl in *.
apply find_unit_spec in H0 as (
Hname&?&
Hsome&
_);
simpl in *;
subst.
apply Forall_elt in Hnone.
congruence.
-
eapply IHnds,
H2.
Qed.
Induction based on order of nodes
Section ordered_nodes_ind.
Context {
PSyn prefs} (
G: @
global PSyn prefs).
Variable P_node :
ident ->
Prop.
Hypothesis Hnode :
forall f n,
find_node f G =
Some n ->
(
forall f',
Is_node_in_block f' (
n_block n) ->
P_node f') ->
P_node f.
Lemma ordered_nodes_ind :
Ordered_nodes G ->
(
forall f n,
find_node f G =
Some n ->
P_node f).
Proof.
End ordered_nodes_ind.
End LORDERED.
Module LOrderedFun
(
Ids :
IDS)
(
Op :
OPERATORS)
(
OpAux :
OPERATORS_AUX Ids Op)
(
Cks :
CLOCKS Ids Op OpAux)
(
Senv :
STATICENV Ids Op OpAux Cks)
(
Syn :
LSYNTAX Ids Op OpAux Cks Senv)
<:
LORDERED Ids Op OpAux Cks Senv Syn.
Include LORDERED Ids Op OpAux Cks Senv Syn.
End LOrderedFun.