From Velus Require Import Common.
From Velus Require Import FunctionalEnvironment.
From Velus Require Import Operators.
From Velus Require Import Clocks.
From Velus Require Import CoreExpr.CESyntax.
From Coq Require Import List.
Free variables
Module Type CEISFREE
(
Ids :
IDS)
(
Op :
OPERATORS)
(
OpAux :
OPERATORS_AUX Ids Op)
(
Import Cks :
CLOCKS Ids Op OpAux)
(
Import Syn :
CESYNTAX Ids Op OpAux Cks).
Inductive Is_free_in_exp :
var_last ->
exp ->
Prop :=
|
FreeEvar:
forall x ty,
Is_free_in_exp (
Var x) (
Evar x ty)
|
FreeElast:
forall x ty,
Is_free_in_exp (
Last x) (
Elast x ty)
|
FreeEwhen1:
forall e c cv x,
Is_free_in_exp x e ->
Is_free_in_exp x (
Ewhen e c cv)
|
FreeEwhen2:
forall e c tx cv,
Is_free_in_exp (
Var c) (
Ewhen e (
c,
tx)
cv)
|
FreeEunop :
forall c op e ty,
Is_free_in_exp c e ->
Is_free_in_exp c (
Eunop op e ty)
|
FreeEbinop :
forall c op e1 e2 ty,
Is_free_in_exp c e1 \/
Is_free_in_exp c e2 ->
Is_free_in_exp c (
Ebinop op e1 e2 ty).
Inductive Is_free_in_aexp :
var_last ->
clock ->
exp ->
Prop :=
|
freeAexp1:
forall ck e x,
Is_free_in_exp x e ->
Is_free_in_aexp x ck e
|
freeAexp2:
forall ck e x,
Is_free_in_clock x ck ->
Is_free_in_aexp (
Var x)
ck e.
Inductive Is_free_in_aexps :
var_last ->
clock ->
list exp ->
Prop :=
|
freeAexps1:
forall ck les x,
Exists (
Is_free_in_exp x)
les ->
Is_free_in_aexps x ck les
|
freeAexps2:
forall ck les x,
Is_free_in_clock x ck ->
Is_free_in_aexps (
Var x)
ck les.
Inductive Is_free_in_cexp :
var_last ->
cexp ->
Prop :=
|
FreeEmerge_cond:
forall i ti l ty,
Is_free_in_cexp (
Var i) (
Emerge (
i,
ti)
l ty)
|
FreeEmerge_branches:
forall i l ty x,
Exists (
Is_free_in_cexp x)
l ->
Is_free_in_cexp x (
Emerge i l ty)
|
FreeEcase_cond:
forall x b l ty,
Is_free_in_exp x b ->
Is_free_in_cexp x (
Ecase b l ty)
|
FreeEcase_branches:
forall x b l d,
Exists (
fun os =>
exists e,
os =
Some e /\
Is_free_in_cexp x e)
l ->
Is_free_in_cexp x (
Ecase b l d)
|
FreeEcase_default :
forall x b l d,
Is_free_in_cexp x d ->
Is_free_in_cexp x (
Ecase b l d)
|
FreeEexp:
forall e x,
Is_free_in_exp x e ->
Is_free_in_cexp x (
Eexp e).
Inductive Is_free_in_acexp :
var_last ->
clock ->
cexp ->
Prop :=
|
freeAcexp1:
forall ck e x,
Is_free_in_cexp x e ->
Is_free_in_acexp x ck e
|
freeAcexp2:
forall ck e x,
Is_free_in_clock x ck ->
Is_free_in_acexp (
Var x)
ck e.
Inductive Is_free_in_rhs :
var_last ->
rhs ->
Prop :=
|
FreeEextcall:
forall x f es ty,
Exists (
Is_free_in_exp x)
es ->
Is_free_in_rhs x (
Eextcall f es ty)
|
FreeEcexp:
forall x e,
Is_free_in_cexp x e ->
Is_free_in_rhs x (
Ecexp e).
Inductive Is_free_in_arhs :
var_last ->
clock ->
rhs ->
Prop :=
|
FreeArhs1 :
forall ck ce x,
Is_free_in_rhs x ce ->
Is_free_in_arhs x ck ce
|
FreeArhs2 :
forall ck ce x,
Is_free_in_clock x ck ->
Is_free_in_arhs (
Var x)
ck ce.
Global Hint Constructors Is_free_in_clock Is_free_in_exp
Is_free_in_aexp Is_free_in_aexps
Is_free_in_cexp Is_free_in_acexp
Is_free_in_rhs Is_free_in_arhs:
nlfree stcfree.
Decision procedure
Lemma Is_free_in_clock_disj:
forall y ck x c,
Is_free_in_clock y (
Con ck x c)
<->
y =
x \/
Is_free_in_clock y ck.
Proof.
intros y ck x c; split; intro HH.
inversion_clear HH; auto.
destruct HH as [HH|HH]; subst; auto with nlfree.
Qed.
Lemma Is_free_in_when_disj:
forall y e x tx c,
Is_free_in_exp y (
Ewhen e (
x,
tx)
c)
<->
y =
Var x \/
Is_free_in_exp y e.
Proof.
intros y e x c; split; intro HH.
inversion_clear HH; auto.
destruct HH as [HH|HH]; subst; auto with nlfree.
Qed.
Fixpoint free_in_clock_dec (
ck :
clock) (
T:
PS.t)
: {
S |
forall x,
PS.In x S <-> (
Is_free_in_clock x ck \/
PS.In x T) }.
refine (
match ck with
|
Cbase =>
exist _ T _
|
Con ck'
x c =>
match free_in_clock_dec ck'
T with
|
exist _ S'
HF =>
exist _ (
PS.add x S')
_
end
end).
-
intro x;
split;
intro HH;
auto.
destruct HH as [
HH|
HH]; [
inversion HH|
exact HH].
-
intro y;
split;
intro HH.
+
apply PS.add_spec in HH as [|
HH];
subst;
auto with nlfree.
apply HF in HH as [|];
auto with nlfree.
+
rewrite Is_free_in_clock_disj in HH.
apply or_assoc in HH.
rewrite PS.add_spec.
destruct HH as [
HH|
HH];
subst;
auto.
right.
apply HF;
auto.
Defined.