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 Operators.
From Velus Require Import Clocks.
From Velus Require Import FunctionalEnvironment.
From Velus Require Import CoreExpr.CESyntax.
From Velus Require Import NLustre.NLSyntax.
From Velus Require Import NLustre.Memories.
Defined variables
Module Type ISDEFINED
(
Ids :
IDS)
(
Op :
OPERATORS)
(
OpAux :
OPERATORS_AUX Ids Op)
(
Import Cks :
CLOCKS Ids Op OpAux)
(
Import CESyn :
CESYNTAX Ids Op OpAux Cks)
(
Import Syn :
NLSYNTAX Ids Op OpAux Cks CESyn)
(
Import Mem :
MEMORIES Ids Op OpAux Cks CESyn Syn).
Logical predicates:
Inductive Is_defined_in_eq :
var_last ->
equation ->
Prop :=
|
DefEqDef:
forall x ck e,
Is_defined_in_eq (
Var x) (
EqDef x ck e)
|
DefEqLast:
forall x ty ck c0 ckrs,
Is_defined_in_eq (
Last x) (
EqLast x ty ck c0 ckrs)
|
DefEqApp:
forall x xs ck f e r,
In x xs ->
Is_defined_in_eq (
Var x) (
EqApp xs ck f e r)
|
DefEqFby:
forall x ck v e r,
Is_defined_in_eq (
Var x) (
EqFby x ck v e r).
Definition Is_defined_in x (
eqs:
list equation) :
Prop :=
List.Exists (
Is_defined_in_eq x)
eqs.
Properties
Global Hint Constructors Is_defined_in_eq :
nldef.
Lemma not_Is_defined_in_eq_EqDef:
forall x i ck ce,
~
Is_defined_in_eq x (
EqDef i ck ce) ->
x <>
Var i.
Proof.
intros x i ck ce H0 xeqi.
rewrite xeqi in H0.
assert (
Is_defined_in_eq (
Var i) (
EqDef i ck ce))
by auto with nldef.
contradiction.
Qed.
Lemma not_Is_defined_in_eq_EqApp:
forall x ys ck f le r,
~
Is_defined_in_eq (
Var x) (
EqApp ys ck f le r) -> ~
List.In x ys.
Proof.
intros * H. intro.
exfalso. apply H; auto with nldef.
Qed.
Lemma Is_defined_in_EqApp:
forall xs ck f es r d,
0 <
length xs ->
Is_defined_in_eq (
Var (
hd d xs)) (
EqApp xs ck f es r).
Proof.
intros * Length.
constructor.
destruct xs; simpl in *; auto; lia.
Qed.
Lemma not_Is_defined_in_eq_EqFby:
forall x i ck v0 le r,
~
Is_defined_in_eq x (
EqFby i ck v0 le r) ->
x <>
Var i.
Proof.
intros x i ck v0 le r H0 xeqi.
rewrite xeqi in H0.
assert (
Is_defined_in_eq (
Var i) (
EqFby i ck v0 le r))
by auto with nldef.
contradiction.
Qed.
Lemma not_Is_defined_in_eq_EqLast:
forall x i ty ck v0 r,
~
Is_defined_in_eq x (
EqLast i ty ck v0 r) ->
x <>
Last i.
Proof.
intros *
H0 xeqi.
rewrite xeqi in H0.
assert (
Is_defined_in_eq (
Last i) (
EqLast i ty ck v0 r))
by auto with nldef.
contradiction.
Qed.
Lemma not_Is_defined_in_cons:
forall x eq eqs,
~
Is_defined_in x (
eq ::
eqs)
<-> ~
Is_defined_in_eq x eq /\ ~
Is_defined_in x eqs.
Proof.
intros x eq eqs. split.
-
intro Hndef; split; intro His_def;
eapply Hndef. now constructor. now constructor 2.
-
intros [Hdef_eq Hdef_eqs] Hdef_all.
inv Hdef_all; eauto.
Qed.
Lemma In_memory_eq_In_defined_eq_gen:
forall x eq S,
PS.In x (
fst (
memory_eq S eq))
->
Is_defined_in_eq (
Var x)
eq \/
PS.In x (
fst S).
Proof.
intros x eq S HH.
destruct eq;
simpl in *;
auto.
apply PS.add_spec in HH as [|];
subst;
auto with nldef.
Qed.
Corollary In_memory_eq_Is_defined_eq:
forall x eq,
PS.In x (
fst (
memory_eq (
PS.empty,
PS.empty)
eq))
->
Is_defined_in_eq (
Var x)
eq.
Proof.
Lemma In_EqFby_Is_defined_in:
forall x ck c0 e r eqs,
In (
EqFby x ck c0 e r)
eqs ->
Is_defined_in (
Var x)
eqs.
Proof.
induction eqs; inversion_clear 1; subst.
now repeat constructor.
constructor 2; intuition.
Qed.
Lemma Is_fby_in_Is_defined_in:
forall x eqs,
Is_fby_in x eqs ->
Is_defined_in (
Var x)
eqs.
Proof.
Lemma Is_last_in_Is_defined_in:
forall x eqs,
Is_last_in x eqs ->
Is_defined_in (
Last x)
eqs.
Proof.
Global Hint Resolve Is_fby_in_Is_defined_in Is_last_in_Is_defined_in :
nldef.
Decision procedures:
Definition defined_eq (
defs: (
PS.t *
PS.t)) (
eq:
equation) : (
PS.t *
PS.t) :=
match eq with
|
EqDef x _ _ => (
PS.add x (
fst defs),
snd defs)
|
EqLast x _ _ _ _ => (
fst defs,
PS.add x (
snd defs))
|
EqApp xs _ _ _ _ => (
ps_adds xs (
fst defs),
snd defs)
|
EqFby x _ _ _ _ => (
PS.add x (
fst defs),
snd defs)
end.
Definition defined (
eqs:
list equation) : (
PS.t *
PS.t) :=
List.fold_left defined_eq eqs (
PS.empty,
PS.empty).
Silly unfolding property:
Lemma defined_eq1 :
forall x m eq,
PS.In x (
fst (
defined_eq m eq))
<->
PS.In x (
fst (
defined_eq (
PS.empty,
PS.empty)
eq)) \/
PS.In x (
fst m).
Proof.
Lemma defined_eq2 :
forall x m eq,
PS.In x (
snd (
defined_eq m eq))
<->
PS.In x (
snd (
defined_eq (
PS.empty,
PS.empty)
eq)) \/
PS.In x (
snd m).
Proof.
intros ?? [];
simpl;
rewrite ?
PS.add_spec, ?
PSF.empty_iff.
all:
split;
auto;
intros;
repeat (
take (
_ \/
_)
and destruct it);
auto;
try now exfalso.
Qed.
Lemma In_fold_left_defined_eq1:
forall x eqs m,
PS.In x (
fst (
List.fold_left defined_eq eqs m))
<->
Exists (
fun eq =>
PS.In x (
fst (
defined_eq (
PS.empty,
PS.empty)
eq)))
eqs \/
PS.In x (
fst m).
Proof.
induction eqs as [|
eq];
simpl.
-
split;
auto.
intros [
Ex|];
auto.
inv Ex.
-
intros ?.
rewrite IHeqs,
defined_eq1.
split;
intros;
repeat (
take (
_ \/
_)
and destruct it);
auto.
inv H;
auto.
Qed.
Lemma In_fold_left_defined_eq2:
forall x eqs m,
PS.In x (
snd (
List.fold_left defined_eq eqs m))
<->
Exists (
fun eq =>
PS.In x (
snd (
defined_eq (
PS.empty,
PS.empty)
eq)))
eqs \/
PS.In x (
snd m).
Proof.
induction eqs as [|
eq];
simpl.
-
split;
auto.
intros [
Ex|];
auto.
inv Ex.
-
intros ?.
rewrite IHeqs,
defined_eq2.
split;
intros;
repeat (
take (
_ \/
_)
and destruct it);
auto.
inv H;
auto.
Qed.
Reflection lemmas:
Lemma defined_eq_spec1:
forall x eq,
Is_defined_in_eq (
Var x)
eq <->
PS.In x (
fst (
defined_eq (
PS.empty,
PS.empty)
eq)).
Proof.
intros x [];
simpl;
rewrite ?
PS.add_spec, ?
ps_adds_spec, ?
PSF.empty_iff.
all:
split; [
intros Is;
inv Is
|
intros;
repeat take (
_ \/
_)
and destruct it;
subst];
auto with nldef;
try now exfalso.
Qed.
Lemma defined_eq_spec2:
forall x eq,
Is_defined_in_eq (
Last x)
eq <->
PS.In x (
snd (
defined_eq (
PS.empty,
PS.empty)
eq)).
Proof.
intros x [];
simpl;
rewrite ?
PS.add_spec, ?
ps_adds_spec, ?
PSF.empty_iff.
all:
split; [
intros Is;
inv Is
|
intros;
repeat take (
_ \/
_)
and destruct it;
subst];
auto with nldef;
try now exfalso.
Qed.
Lemma defined_spec1:
forall x eqs,
Is_defined_in (
Var x)
eqs <->
PS.In x (
fst (
defined eqs)).
Proof.
Lemma defined_spec2:
forall x eqs,
Is_defined_in (
Last x)
eqs <->
PS.In x (
snd (
defined eqs)).
Proof.
Lemma Is_defined_in_eq_dec:
forall x eq, {
Is_defined_in_eq x eq}+{~
Is_defined_in_eq x eq}.
Proof.
Lemma Is_defined_in_dec:
forall x eqs, {
Is_defined_in x eqs}+{~
Is_defined_in x eqs}.
Proof.
Lemma decidable_Is_defined_in:
forall x eqs,
Decidable.decidable (
Is_defined_in x eqs).
Proof.
Properties
Lemma Is_defined_in_var_defined:
forall x eq,
Is_defined_in_eq (
Var x)
eq <->
List.In x (
var_defined eq).
Proof.
Corollary Is_defined_in_vars_defined:
forall x eqs,
Is_defined_in (
Var x)
eqs
<->
In x (
vars_defined eqs).
Proof.
Lemma Is_defined_in_last_defined:
forall x eq,
Is_defined_in_eq (
Last x)
eq <->
List.In x (
last_defined eq).
Proof.
Corollary Is_defined_in_lasts_defined:
forall x eqs,
Is_defined_in (
Last x)
eqs
<->
In x (
lasts_defined eqs).
Proof.
Lemma Is_defined_in_cons:
forall x eq eqs,
Is_defined_in x (
eq ::
eqs) ->
Is_defined_in_eq x eq
\/ (~
Is_defined_in_eq x eq /\
Is_defined_in x eqs).
Proof.
Lemma Is_defined_in_In:
forall x eqs,
Is_defined_in x eqs ->
exists eq,
In eq eqs /\
Is_defined_in_eq x eq.
Proof.
Lemma node_output_defined_in_eqs:
forall n x,
In x (
map fst n.(
n_out)) ->
Is_defined_in (
Var x)
n.(
n_eqs).
Proof.
End ISDEFINED.
Module IsDefinedFun
(
Ids :
IDS)
(
Op :
OPERATORS)
(
OpAux :
OPERATORS_AUX Ids Op)
(
Cks :
CLOCKS Ids Op OpAux)
(
CESyn :
CESYNTAX Ids Op OpAux Cks)
(
Syn :
NLSYNTAX Ids Op OpAux Cks CESyn)
(
Mem :
MEMORIES Ids Op OpAux Cks CESyn Syn)
<:
ISDEFINED Ids Op OpAux Cks CESyn Syn Mem.
Include ISDEFINED Ids Op OpAux Cks CESyn Syn Mem.
End IsDefinedFun.