From Coq Require Import List.
Import List.ListNotations.
Open Scope list_scope.
From Coq Require Import Recdef.
From Velus Require Import Common.
From Velus Require Import CommonProgram.
From Velus Require Import Operators.
From Velus Require Import Clocks.
From Velus Require Import Environment.
From Velus Require Import CoreExpr.CESyntax.
From Velus Require Import CoreExpr.CETyping.
From Velus Require Import NLustre.NLSyntax.
From Velus Require Import NLustre.NLTyping.
From Velus Require Import NLustre.NLOrdered.
From Velus Require Import NLustre.DupRegRem.DRR.
Module Type DRRTYPING
(
Import Ids :
IDS)
(
Import Op :
OPERATORS)
(
Import OpAux :
OPERATORS_AUX Ids Op)
(
Import Cks :
CLOCKS Ids Op OpAux)
(
Import CESyn :
CESYNTAX Ids Op OpAux Cks)
(
Import CETyp :
CETYPING Ids Op OpAux Cks CESyn)
(
Import Syn :
NLSYNTAX Ids Op OpAux Cks CESyn)
(
Import Ord :
NLORDERED Ids Op OpAux Cks CESyn Syn)
(
Import Typ :
NLTYPING Ids Op OpAux Cks CESyn Syn Ord CETyp)
(
Import DRR :
DRR Ids Op OpAux Cks CESyn Syn).
Section rename.
Variable sub :
Env.t ident.
Variable inouts :
list (
ident * (
type *
bool)).
Variable vars vars' :
list (
ident * (
type *
bool)).
Hypothesis Hsub :
forall x y ty islast,
Env.find x sub =
Some y ->
In (
x, (
ty,
islast)) (
inouts ++
vars) ->
In (
y, (
ty,
islast)) (
inouts ++
vars').
Hypothesis Hnsub :
forall x ty islast,
Env.find x sub =
None ->
In (
x, (
ty,
islast)) (
inouts ++
vars) ->
In (
x, (
ty,
islast)) (
inouts ++
vars').
Hypothesis Hlast :
forall x ty,
In (
x, (
ty,
true)) (
inouts ++
vars) ->
In (
x, (
ty,
true)) (
inouts ++
vars').
Lemma rename_in_var_wt :
forall x ty islast,
In (
x, (
ty,
islast)) (
inouts++
vars) ->
In (
rename_in_var sub x, (
ty,
islast)) (
inouts++
vars').
Proof.
Local Hint Resolve rename_in_var_wt :
nltyping.
Variable (
G :
global).
Lemma rename_in_clock_wt :
forall ck,
wt_clock G.(
types) (
inouts++
vars)
ck ->
wt_clock G.(
types) (
inouts++
vars') (
rename_in_clock sub ck).
Proof.
induction ck; intros * Hwt; inv Hwt; auto with nltyping.
simpl. econstructor; eauto with nltyping.
Qed.
Lemma rename_in_exp_wt :
forall e,
wt_exp G.(
types) (
inouts++
vars)
e ->
wt_exp G.(
types) (
inouts++
vars') (
rename_in_exp sub e).
Proof.
intros *
Hwt;
induction Hwt;
simpl;
econstructor;
eauto with nltyping.
1,2:
repeat rewrite rename_in_exp_typeof;
auto.
Qed.
Lemma rename_in_cexp_wt :
forall e,
wt_cexp G.(
types) (
inouts++
vars)
e ->
wt_cexp G.(
types) (
inouts++
vars') (
rename_in_cexp sub e).
Proof.
Lemma rename_in_rhs_wt :
forall e,
wt_rhs G.(
types)
G.(
externs) (
inouts++
vars)
e ->
wt_rhs G.(
types)
G.(
externs) (
inouts++
vars') (
rename_in_rhs sub e).
Proof.
Local Hint Resolve rename_in_var_wt rename_in_clock_wt rename_in_exp_wt rename_in_cexp_wt rename_in_rhs_wt :
nltyping.
Lemma rename_in_equation_wt :
forall equ,
(
forall x,
In x (
var_defined equ) ->
Env.find x sub =
None) ->
wt_equation G (
inouts++
vars)
equ ->
wt_equation G (
inouts++
vars') (
rename_in_equation sub equ).
Proof with
End rename.
Definition idty (
vars :
list (
ident * (
type *
clock *
bool))) :=
map (
fun x => (
fst x, (
fst (
fst (
snd x)),
snd (
snd x))))
vars.
Lemma remove_dup_regs_once_wt :
forall G inouts vars eqs,
NoDup (
map fst inouts++
map fst vars) ->
NoDup (
vars_defined eqs) ->
Forall (
fun x => ~
InMembers x inouts) (
vars_defined (
filter is_fby eqs)) ->
Forall (
fun '(
x, (
_,
_,
islast)) =>
islast =
true -> ~
In x (
vars_defined (
filter is_fby eqs)))
vars ->
Forall (
wt_equation G (
inouts++
idty vars))
eqs ->
let (
vars',
eqs') :=
remove_dup_regs_eqs_once vars eqs in
Forall (
wt_equation G (
inouts++
idty vars'))
eqs'.
Proof.
intros *
Hndv Hnd Hinouts Hlasts Hwt.
destruct (
remove_dup_regs_eqs_once _)
eqn:
Honce.
inv Honce.
unfold subst_and_filter_equations.
rewrite Forall_map,
Forall_filter.
eapply Forall_impl_In;
eauto.
intros ?
Hineq Hwt'
Hfilter.
eapply rename_in_equation_wt; [| | | |
eauto].
-
intros *
Hfind Hin.
assert (~
InMembers x inouts)
as Hnx.
{
apply find_duplicates_spec in Hfind as (?&?&?&?&?&
Hin1&
_&
_).
apply Forall_flat_map,
Forall_filter in Hinouts.
simpl_Forall.
specialize (
Hinouts eq_refl).
simpl_Forall.
auto. }
assert (~
InMembers y inouts)
as Hny.
{
apply find_duplicates_spec in Hfind as (?&?&?&?&?&
_&
Hin2&
_).
apply Forall_flat_map,
Forall_filter in Hinouts.
simpl_Forall.
specialize (
Hinouts eq_refl).
simpl_Forall.
auto. }
rewrite in_app_iff in *.
destruct Hin as [
Hin|
Hin].
1:(
exfalso;
eauto using In_InMembers).
right.
assert (
Hfind':=
Hfind).
eapply find_duplicates_spec in Hfind as (?&?&?&?&?&
Hwt1&
Hwt2&
_).
eapply Forall_forall in Hwt1;
eauto.
eapply Forall_forall in Hwt2;
eauto.
inv Hwt1.
inv Hwt2.
rewrite in_app_iff in H4,
H9.
destruct H4 as [
Hin1|
Hin1],
H9 as [
Hin2|
Hin2].
1-3:(
exfalso;
eauto using In_InMembers).
simpl_In.
eapply NoDupMembers_det in Hin1;
eauto. 2:
apply fst_NoDupMembers;
eauto using NoDup_app_r.
inv Hin1.
unfold idty,
subst_and_filter_vars.
solve_In.
eapply find_duplicates_irrefl in Hfind';
eauto.
apply Env.Props.P.F.not_mem_in_iff in Hfind'.
rewrite Hfind';
auto.
-
intros *
Hfind Hin.
rewrite in_app_iff in *.
destruct Hin as [
Hin|
Hin];
auto.
right.
unfold idty,
subst_and_filter_vars in *.
solve_In.
rewrite Env.mem_find,
Hfind;
auto.
-
intros *
In.
rewrite in_app_iff in *.
destruct In as [
In|
In];
auto.
right.
unfold idty,
subst_and_filter_vars.
solve_In.
simpl_Forall.
apply Bool.negb_true_iff,
Env.Props.P.F.not_mem_in_iff.
intros ?;
eapply Hlasts;
eauto using find_duplicates_In.
-
intros *
Hindef.
destruct (
Env.find _ _)
eqn:
Hfind;
auto.
exfalso.
apply Env.find_In in Hfind.
assert (
Hisfby:=
Hindef).
eapply find_duplicates_is_fby in Hisfby;
eauto.
destruct a;
simpl in *;
try congruence.
inv Hindef;
auto.
rewrite Bool.negb_true_iff, <-
Env.Props.P.F.not_mem_in_iff in Hfilter.
congruence.
Qed.
Lemma remove_dup_regs_eqs_wt :
forall G inouts vars eqs vars'
eqs',
NoDup (
map fst inouts ++
map fst vars) ->
NoDup (
vars_defined eqs) ->
Forall (
fun x => ~
InMembers x inouts) (
vars_defined (
filter is_fby eqs)) ->
Forall (
fun '(
x, (
_,
_,
islast)) =>
islast =
true -> ~
In x (
vars_defined (
filter is_fby eqs)))
vars ->
Forall (
wt_equation G (
inouts ++
idty vars))
eqs ->
remove_dup_regs_eqs vars eqs = (
vars',
eqs') ->
Forall (
wt_equation G (
inouts ++
idty vars'))
eqs'.
Proof.
Definition idty' (
vars :
list (
ident * (
type *
clock))) :=
map (
fun x => (
fst x, (
fst (
snd x),
false)))
vars.
Lemma remove_dup_regs_node_wt :
forall G n,
wt_node G n ->
wt_node (
remove_dup_regs G) (
remove_dup_regs_node n).
Proof.
Theorem remove_dup_regs_wt :
forall G,
wt_global G ->
wt_global (
remove_dup_regs G).
Proof.
End DRRTYPING.
Module DrrTypingFun
(
Ids :
IDS)
(
Op :
OPERATORS)
(
OpAux :
OPERATORS_AUX Ids Op)
(
Cks :
CLOCKS Ids Op OpAux)
(
CESyn :
CESYNTAX Ids Op OpAux Cks)
(
CETyp :
CETYPING Ids Op OpAux Cks CESyn)
(
Syn :
NLSYNTAX Ids Op OpAux Cks CESyn)
(
Ord :
NLORDERED Ids Op OpAux Cks CESyn Syn)
(
Typ :
NLTYPING Ids Op OpAux Cks CESyn Syn Ord CETyp)
(
DRR :
DRR Ids Op OpAux Cks CESyn Syn)
<:
DRRTYPING Ids Op OpAux Cks CESyn CETyp Syn Ord Typ DRR.
Include DRRTYPING Ids Op OpAux Cks CESyn CETyp Syn Ord Typ DRR.
End DrrTypingFun.