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.IsDefined.
From Velus Require Import NLustre.Memories.
From Coq Require Import Sorting.Permutation.
Stack variables
Module Type ISVARIABLE
(
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)
(
Import IsD :
ISDEFINED Ids Op OpAux Cks CESyn Syn Mem).
Inductive Is_variable_in_eq :
ident ->
equation ->
Prop :=
|
VarEqDef:
forall x ck e,
Is_variable_in_eq x (
EqDef x ck e)
|
VarEqApp:
forall x xs ck f e r,
In x xs ->
Is_variable_in_eq x (
EqApp xs ck f e r).
Definition Is_variable_in (
x:
ident) (
eqs:
list equation) :
Prop :=
List.Exists (
Is_variable_in_eq x)
eqs.
Global Hint Constructors Is_variable_in_eq :
nldef.
Properties
Lemma not_Is_variable_in_EqDef:
forall x ck y e,
~
Is_variable_in_eq x (
EqDef y ck e) ->
x <>
y.
Proof.
intros ** Hxy. subst x. auto with nldef.
Qed.
Lemma not_Is_variable_in_EqApp:
forall x ys ck f e r,
~
Is_variable_in_eq x (
EqApp ys ck f e r) -> ~
List.In x ys.
Proof.
eauto with nldef. Qed.
Lemma Is_variable_in_eq_Is_defined_in_eq:
forall x eq,
Is_variable_in_eq x eq
->
Is_defined_in_eq (
Var x)
eq.
Proof.
destruct eq; inversion_clear 1; auto with nldef.
Qed.
Lemma Is_variable_in_Is_defined_in:
forall x eqs,
Is_variable_in x eqs
->
Is_defined_in (
Var x)
eqs.
Proof.
Global Hint Resolve Is_variable_in_eq_Is_defined_in_eq Is_variable_in_Is_defined_in :
nldef.
Lemma not_Is_defined_in_eq_not_Is_variable_in_eq:
forall x eq, ~
Is_defined_in_eq (
Var x)
eq -> ~
Is_variable_in_eq x eq.
Proof.
intros * Hnidi.
contradict Hnidi; eauto with nldef.
Qed.
Lemma not_Is_defined_in_not_Is_variable_in:
forall x eqs, ~
Is_defined_in (
Var x)
eqs -> ~
Is_variable_in x eqs.
Proof.
intros * Hnidi.
contradict Hnidi; eauto with nldef.
Qed.
Lemma Is_variable_in_var_defined:
forall x eqs,
Is_variable_in x eqs
<->
In x (
vars_defined (
filter (
notb is_fby)
eqs)).
Proof.
intros.
unfold Is_variable_in,
vars_defined,
notb.
split;
intros In.
-
simpl_Exists.
solve_In.
1,2:
inv In;
simpl;
auto.
-
simpl_In.
solve_Exists.
destruct x0;
simpl in *;
try (
take (
_ \/
_)
and destruct it);
subst;
try (
now exfalso);
auto with nldef.
Qed.
Lemma In_EqDef_Is_variable_in:
forall x ck e eqs,
In (
EqDef x ck e)
eqs ->
Is_variable_in x eqs.
Proof.
induction eqs; inversion_clear 1; subst.
now repeat constructor.
constructor 2; intuition.
Qed.
Lemma In_EqApp_Is_variable_in:
forall x xs ck f es eqs r,
List.In x xs ->
In (
EqApp xs ck f es r)
eqs ->
Is_variable_in x eqs.
Proof.
induction eqs; inversion_clear 2.
- now subst; repeat constructor.
- constructor; eapply IHeqs; eauto.
Qed.
Decision procedure
Definition variable_eq (
vars:
PS.t) (
eq:
equation) :
PS.t :=
match eq with
|
EqDef x _ _ =>
PS.add x vars
|
EqApp xs _ _ _ _ =>
ps_adds xs vars
|
EqLast _ _ _ _ _
|
EqFby _ _ _ _ _ =>
vars
end.
Definition variables (
eqs:
list equation) :
PS.t :=
List.fold_left variable_eq eqs PS.empty.
Properties
Lemma In_variable_eq:
forall x eq m,
PS.In x (
variable_eq m eq) <->
PS.In x m \/
PS.In x (
variable_eq PS.empty eq).
Proof.
Lemma In_fold_left_variable_eq:
forall x eqs m,
PS.In x (
List.fold_left variable_eq eqs m)
<->
Exists (
fun eq =>
PS.In x (
variable_eq PS.empty eq))
eqs \/
PS.In x m.
Proof.
induction eqs as [|
eq];
simpl.
-
split;
auto.
intros [
Ex|];
auto.
inv Ex.
-
intros ?.
rewrite IHeqs,
In_variable_eq.
split;
intros;
repeat (
take (
_ \/
_)
and destruct it);
auto.
inv H;
auto.
Qed.
Ltac not_Is_variable x y :=
match goal with
|
H: ~
Is_variable_in_eq x (
EqDef y _ _) |-
_ =>
apply not_Is_variable_in_EqDef in H
|
H: ~
Is_variable_in_eq x (
EqApp y _ _ _ _) |-
_ =>
apply not_Is_variable_in_EqApp in H
end.
Lemma Is_variable_in_eq_dec:
forall x eq, {
Is_variable_in_eq x eq}+{~
Is_variable_in_eq x eq}.
Proof.
intros x eq.
destruct eq as [
y cae| |
ys f lae|
y v0 lae].
-
destruct (
ident_eq_dec x y);
subst;
auto with nldef.
right.
inversion 1;
subst;
auto with nldef.
-
right.
inversion 1.
-
destruct (
in_dec ident_eq_dec x ys);
auto with nldef.
right.
inversion 1;
subst;
auto with nldef.
-
right.
inversion 1.
Qed.
Lemma Is_variable_in_cons:
forall x eq eqs,
Is_variable_in x (
eq ::
eqs) ->
Is_variable_in_eq x eq
\/ (~
Is_variable_in_eq x eq /\
Is_variable_in x eqs).
Proof.
Lemma not_Is_variable_in_cons:
forall x eq eqs,
~
Is_variable_in x (
eq ::
eqs)
<-> ~
Is_variable_in_eq x eq /\ ~
Is_variable_in x eqs.
Proof.
Lemma Is_variable_in_variables:
forall x eqs,
PS.In x (
variables eqs)
<->
Is_variable_in x eqs.
Proof.
End ISVARIABLE.
Module IsVariableFun
(
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)
(
IsD :
ISDEFINED Ids Op OpAux Cks CESyn Syn Mem)
<:
ISVARIABLE Ids Op OpAux Cks CESyn Syn Mem IsD.
Include ISVARIABLE Ids Op OpAux Cks CESyn Syn Mem IsD.
End IsVariableFun.