From Velus Require Import Common.
From Velus Require Import CommonProgram.
From Velus Require Import Operators.
From Velus Require Import CoreExpr.CESyntax.
From Velus Require Import Clocks.
From Coq Require Import Permutation.
From Coq Require Import List.
Import List.ListNotations.
Open Scope list_scope.
Module Type STCSYNTAX
(
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).
Transition constraints
Inductive resetconstr :=
|
ResState :
ident ->
type ->
const ->
resetconstr
|
ResInst :
ident ->
ident ->
resetconstr.
Inductive updateconstr :=
|
UpdLast :
ident ->
cexp ->
updateconstr
|
UpdNext :
ident ->
exp ->
updateconstr
|
UpdInst :
ident ->
list ident ->
ident ->
list exp ->
updateconstr.
Inductive trconstr :=
|
TcDef :
clock ->
ident ->
rhs ->
trconstr
|
TcReset :
clock ->
resetconstr ->
trconstr
|
TcUpdate :
clock ->
list clock ->
updateconstr ->
trconstr.
Definition variables_tc (
tc:
trconstr):
list ident :=
match tc with
|
TcDef _ x _ => [
x]
|
TcUpdate _ _ (
UpdInst _ xs _ _) =>
xs
|
_ => []
end.
Definition variables :=
flat_map variables_tc.
Inductive Is_reset_state_in_tc:
ident ->
clock ->
trconstr ->
Prop :=
ResetTcReset:
forall x ck ty ro,
Is_reset_state_in_tc x ck (
TcReset ck (
ResState x ty ro)).
Definition Is_reset_state_in (
x:
ident) (
ck:
clock) (
tcs:
list trconstr) :
Prop :=
Exists (
Is_reset_state_in_tc x ck)
tcs.
Inductive Last_with_reset_in_tc:
ident ->
list clock ->
trconstr ->
Prop :=
|
Last_with_reset_in_tc_intro:
forall x ck ckrs e,
Last_with_reset_in_tc x ckrs (
TcUpdate ck ckrs (
UpdLast x e)).
Global Hint Constructors Last_with_reset_in_tc :
stcsyntax.
Definition Last_with_reset_in (
s:
ident) (
ckrs:
list clock) (
tcs:
list trconstr) :
Prop :=
Exists (
Last_with_reset_in_tc s ckrs)
tcs.
Definition last_consistency (
tcs:
list trconstr) :
Prop :=
forall s ckrs,
Last_with_reset_in s ckrs tcs ->
(
forall ckr,
In ckr ckrs <->
Is_reset_state_in s ckr tcs).
Inductive Next_with_reset_in_tc:
ident ->
list clock ->
trconstr ->
Prop :=
|
Next_with_reset_in_tc_intro:
forall x ck ckrs e,
Next_with_reset_in_tc x ckrs (
TcUpdate ck ckrs (
UpdNext x e)).
Global Hint Constructors Next_with_reset_in_tc :
stcsyntax.
Definition Next_with_reset_in (
s:
ident) (
ckrs:
list clock) (
tcs:
list trconstr) :
Prop :=
Exists (
Next_with_reset_in_tc s ckrs)
tcs.
Definition next_consistency (
tcs:
list trconstr) :
Prop :=
forall s ckrs,
Next_with_reset_in s ckrs tcs ->
(
forall ckr,
In ckr ckrs <->
Is_reset_state_in s ckr tcs).
Inductive Is_reset_inst_in_tc:
ident ->
clock ->
trconstr ->
Prop :=
|
SubTcReset:
forall s ck b,
Is_reset_inst_in_tc s ck (
TcReset ck (
ResInst s b)).
Definition Is_reset_inst_in (
s:
ident) (
ck :
clock) :=
Exists (
Is_reset_inst_in_tc s ck).
Inductive Is_update_inst_in_tc:
ident ->
trconstr ->
Prop :=
|
SubTcUpd:
forall s xs ck ckrs b es,
Is_update_inst_in_tc s (
TcUpdate ck ckrs (
UpdInst s xs b es)).
Definition Is_update_inst_in (
s:
ident) :=
Exists (
Is_update_inst_in_tc s).
Inductive Inst_with_reset_in_tc:
ident ->
list clock ->
trconstr ->
Prop :=
Inst_with_reset_in_tc_intro:
forall s ck ckrs ys f es,
Inst_with_reset_in_tc s ckrs (
TcUpdate ck ckrs (
UpdInst s ys f es)).
Global Hint Constructors Inst_with_reset_in_tc :
stcsyntax.
Definition Inst_with_reset_in (
s:
ident) (
ckrs:
list clock) (
tcs:
list trconstr) :
Prop :=
Exists (
Inst_with_reset_in_tc s ckrs)
tcs.
Definition inst_consistency (
tcs:
list trconstr) :
Prop :=
forall s ckrs,
Inst_with_reset_in s ckrs tcs ->
(
forall ckr,
In ckr ckrs <->
Is_reset_inst_in s ckr tcs).
Fixpoint state_resets_of (
tcs:
list trconstr) :
list ident :=
match tcs with
| [] => []
|
TcReset ck (
ResState x _ _) ::
tcs =>
x :: (
state_resets_of tcs)
|
_ ::
tcs =>
state_resets_of tcs
end.
Fixpoint lasts_of (
tcs:
list trconstr) :
list (
ident *
type) :=
match tcs with
| [] => []
|
TcUpdate _ _ (
UpdLast x e) ::
tcs => (
x,
typeofc e) :: (
lasts_of tcs)
|
_ ::
tcs =>
lasts_of tcs
end.
Fixpoint nexts_of (
tcs:
list trconstr) :
list (
ident *
type) :=
match tcs with
| [] => []
|
TcUpdate _ _ (
UpdNext x e) ::
tcs => (
x,
typeof e) :: (
nexts_of tcs)
|
_ ::
tcs =>
nexts_of tcs
end.
Fixpoint inst_resets_of (
tcs:
list trconstr) :
list (
ident *
ident) :=
match tcs with
| [] => []
|
TcReset _ (
ResInst s b) ::
tcs => (
s,
b) ::
inst_resets_of tcs
|
_ ::
tcs =>
inst_resets_of tcs
end.
Fixpoint insts_of (
tcs:
list trconstr) :
list (
ident *
ident) :=
match tcs with
| [] => []
|
TcUpdate _ _ (
UpdInst s _ b _) ::
tcs => (
s,
b) ::
insts_of tcs
|
_ ::
tcs =>
insts_of tcs
end.
Definition mems_of_states {
A B C} :
list (
ident * (
A *
B *
C)) ->
list (
ident *
B) :=
map (
fun x => (
fst x,
snd (
fst (
snd x)))).
Record system {
prefs:
PS.t} :=
System {
s_name :
ident;
s_in :
list (
ident * (
type *
clock));
s_vars :
list (
ident * (
type *
clock));
s_lasts :
list (
ident * (
const *
type *
clock));
s_nexts :
list (
ident * (
const *
type *
clock));
s_subs :
list (
ident *
ident);
s_out :
list (
ident * (
type *
clock));
s_tcs :
list trconstr;
s_ingt0 : 0 <
length s_in;
s_nodup :
NoDup (
map fst s_in ++
map fst s_vars ++
map fst s_out ++
map fst s_lasts ++
map fst s_nexts);
s_nodup_states_subs:
NoDup (
map fst s_lasts ++
map fst s_nexts ++
map fst s_subs);
s_vars_out_in_tcs :
Permutation (
map fst s_vars ++
map fst s_out) (
variables s_tcs);
s_lasts_in_tcs :
Permutation (
map fst s_lasts) (
map fst (
lasts_of s_tcs));
s_last_consistency :
last_consistency s_tcs;
s_nexts_in_tcs :
Permutation (
map fst s_nexts) (
map fst (
nexts_of s_tcs));
s_next_consistency :
next_consistency s_tcs;
s_state_reset_incl :
incl (
state_resets_of s_tcs) (
map fst (
lasts_of s_tcs++
nexts_of s_tcs));
s_subs_in_tcs :
forall f,
In f (
map snd s_subs)
<->
In f (
map snd (
insts_of s_tcs ++
inst_resets_of s_tcs));
s_subs_insts_of :
Permutation s_subs (
insts_of s_tcs);
s_inst_consistency:
inst_consistency s_tcs;
s_inst_reset_incl :
incl (
inst_resets_of s_tcs) (
insts_of s_tcs);
s_good :
Forall (
AtomOrGensym prefs) (
map fst (
s_in ++
s_vars ++
s_out))
/\
Forall (
AtomOrGensym prefs) (
map fst s_lasts)
/\
Forall (
AtomOrGensym prefs) (
map fst s_nexts)
/\
Forall (
AtomOrGensym prefs) (
map fst s_subs)
/\
atom s_name
}.
Global Instance system_unit {
prefs} :
ProgramUnit (@
system prefs) :=
{
name :=
s_name; }.
Global Instance system_state_unit {
prefs} :
ProgramStateUnit (@
system prefs)
type :=
{
state_variables :=
fun s =>
mems_of_states (
s_lasts s ++
s_nexts s);
instance_variables :=
s_subs }.
Lemma inst_in_Inst_with_reset_in:
forall tcs s,
Is_update_inst_in s tcs ->
exists rst,
Inst_with_reset_in s rst tcs.
Proof.
induction 1 as [?? Step|].
- inv Step. exists ckrs; left; constructor.
- destruct IHExists.
eexists; right; eauto.
Qed.
Lemma inst_in_insts_of:
forall tcs s,
Is_update_inst_in s tcs <->
InMembers s (
insts_of tcs).
Proof.
induction tcs as [|
tc];
simpl.
-
split;
inversion 1.
-
intros.
unfold Is_update_inst_in in *.
rewrite Exists_cons,
IHtcs.
cases;
intuition;
try take (
Is_update_inst_in_tc _ _)
and inv it.
+
constructor;
auto.
+
now right.
+
take (
InMembers _ _)
and inv it;
auto.
left;
constructor.
Qed.
Lemma s_nodup_lasts {
prefs}:
forall (
b: @
system prefs),
NoDupMembers b.(
s_lasts).
Proof.
Lemma s_nodup_nexts {
prefs}:
forall (
b: @
system prefs),
NoDupMembers b.(
s_nexts).
Proof.
Lemma s_nodup_lasts_nexts {
prefs}:
forall (
b: @
system prefs),
NoDupMembers (
b.(
s_lasts) ++
b.(
s_nexts)).
Proof.
Lemma s_nodup_subs {
prefs}:
forall (
b: @
system prefs),
NoDupMembers b.(
s_subs).
Proof.
Lemma s_nodup_vars {
prefs}:
forall (
b: @
system prefs),
NoDupMembers (
s_in b ++
s_vars b ++
s_out b).
Proof.
Lemma s_nodup_variables {
prefs}:
forall (
b: @
system prefs),
NoDup (
variables b.(
s_tcs)).
Proof.
Record program {
prefs} :=
Program {
types :
list type;
externs :
list (
ident * (
list ctype *
ctype));
systems :
list (@
system prefs)
}.
Arguments Program {
_}.
Global Program Instance program_program {
prefs}:
CommonProgram.Program (@
system prefs) (@
program prefs) :=
{
units :=
systems;
update :=
fun p =>
Program p.(
types)
p.(
externs) }.
Definition find_system {
prefs} :
ident -> (@
program prefs) ->
option (
system *
program) :=
find_unit.
Remark find_system_other {
prefs}:
forall b P (
bl: @
system prefs)
types externs,
bl.(
s_name) <>
b ->
find_system b (
Program types externs (
bl ::
P)) =
find_system b (
Program types externs P).
Proof.
Lemma Inst_with_reset_in_Is_update_inst_in:
forall tcs s rst,
Inst_with_reset_in s rst tcs ->
Is_update_inst_in s tcs.
Proof.
induction 1 as [?? Step|].
- inv Step; left; constructor.
- right; auto.
Qed.
Lemma Last_with_reset_in_cons_not_last:
forall tcs tc s rst,
(
forall s ck ckrs e,
tc <>
TcUpdate ck ckrs (
UpdLast s e)) ->
(
Last_with_reset_in s rst (
tc ::
tcs) <->
Last_with_reset_in s rst tcs).
Proof.
intros * Neq; split.
- inversion_clear 1 as [?? Step|]; auto.
inv Step; exfalso; eapply Neq; eauto.
- right; auto.
Qed.
Lemma Next_with_reset_in_cons_not_next:
forall tcs tc s rst,
(
forall s ck ckrs e,
tc <>
TcUpdate ck ckrs (
UpdNext s e)) ->
(
Next_with_reset_in s rst (
tc ::
tcs) <->
Next_with_reset_in s rst tcs).
Proof.
intros * Neq; split.
- inversion_clear 1 as [?? Step|]; auto.
inv Step; exfalso; eapply Neq; eauto.
- right; auto.
Qed.
Lemma Inst_with_reset_in_cons_not_step:
forall tcs tc s rst,
(
forall s ck ckrs ys f es,
tc <>
TcUpdate ck ckrs (
UpdInst s ys f es)) ->
(
Inst_with_reset_in s rst (
tc ::
tcs) <->
Inst_with_reset_in s rst tcs).
Proof.
intros * Neq; split.
- inversion_clear 1 as [?? Step|]; auto.
inv Step; exfalso; eapply Neq; eauto.
- right; auto.
Qed.
Lemma insts_of_In':
forall tcs s b,
In (
s,
b) (
insts_of tcs) ->
exists xs ck ckrs es,
In (
TcUpdate ck ckrs (
UpdInst s xs b es))
tcs.
Proof.
induction tcs as [|[]]; simpl; try contradiction; intros * Hin;
try now edestruct IHtcs as (?&?&?&?&?); eauto 6.
cases; [| |destruct Hin as [E|]].
1,2,4:edestruct IHtcs as (?&?&?&?&?); eauto 6.
inv E; eauto 6.
Qed.
Lemma inst_resets_of_app:
forall tcs tcs',
inst_resets_of (
tcs ++
tcs') =
inst_resets_of tcs ++
inst_resets_of tcs'.
Proof.
induction tcs as [|[]]; intros; simpl; cases; simpl; try f_equal; auto.
Qed.
Definition is_update_inst_in_tc_b (
s:
ident) (
tc:
trconstr) :
bool :=
match tc with
|
TcUpdate _ _ (
UpdInst s'
_ _ _) =>
ident_eqb s s'
|
_ =>
false
end.
Definition is_update_inst_in_tcs_b (
s:
ident) (
tcs:
list trconstr) :
bool :=
existsb (
is_update_inst_in_tc_b s)
tcs.
Definition is_reset_inst_in_tc_b (
s:
ident) (
ck:
clock) (
tc:
trconstr) :
bool :=
match tc with
|
TcReset ck' (
ResInst s'
_) =>
ident_eqb s s' &&
clock_eq ck ck'
|
_ =>
false
end.
Definition is_reset_inst_in_tcs_b (
s:
ident) (
ck:
clock) (
tcs:
list trconstr) :
bool :=
existsb (
is_reset_inst_in_tc_b s ck)
tcs.
Fact is_update_inst_in_tc_reflect:
forall s tc,
Is_update_inst_in_tc s tc <->
is_update_inst_in_tc_b s tc =
true.
Proof.
destruct tc;
simpl;
cases;
simpl;
split;
try discriminate;
try now inversion 1.
-
inversion_clear 1;
apply ident_eqb_refl.
-
rewrite ident_eqb_eq;
intros;
subst;
constructor.
Qed.
Corollary is_update_inst_in_reflect:
forall s tcs,
Is_update_inst_in s tcs <->
is_update_inst_in_tcs_b s tcs =
true.
Proof.
Lemma Is_update_inst_in_dec:
forall s tcs,
{
Is_update_inst_in s tcs } + { ~
Is_update_inst_in s tcs }.
Proof.
Fact Is_reset_inst_in_tc_reflect:
forall s ck tc,
Is_reset_inst_in_tc s ck tc <->
is_reset_inst_in_tc_b s ck tc =
true.
Proof.
Corollary Is_reset_inst_in_reflect:
forall s ck tcs,
Is_reset_inst_in s ck tcs <->
is_reset_inst_in_tcs_b s ck tcs =
true.
Proof.
Lemma Is_reset_inst_in_dec:
forall s ck tcs,
{
Is_reset_inst_in s ck tcs } + { ~
Is_reset_inst_in s ck tcs }.
Proof.
Lemma variables_app:
forall tcs tcs',
variables (
tcs ++
tcs') =
variables tcs ++
variables tcs'.
Proof.
unfold variables.
induction tcs as [|[]];
simpl;
intros;
auto with datatypes.
-
rewrite <-
app_assoc;
f_equal;
auto.
Qed.
Lemma insts_of_app:
forall tcs tcs',
insts_of (
tcs ++
tcs') =
insts_of tcs ++
insts_of tcs'.
Proof.
unfold insts_of.
induction tcs as [|[]];
simpl;
cases;
simpl;
intros;
auto with datatypes.
Qed.
Lemma state_resets_of_app:
forall tcs tcs',
state_resets_of (
tcs ++
tcs') =
state_resets_of tcs ++
state_resets_of tcs'.
Proof.
induction tcs as [|[]]; simpl; cases; simpl; auto; setoid_rewrite IHtcs; auto.
Qed.
Lemma lasts_of_app:
forall tcs tcs',
lasts_of (
tcs ++
tcs') =
lasts_of tcs ++
lasts_of tcs'.
Proof.
induction tcs as [|[]]; simpl; cases; simpl; auto; setoid_rewrite IHtcs; auto.
Qed.
Lemma nexts_of_app:
forall tcs tcs',
nexts_of (
tcs ++
tcs') =
nexts_of tcs ++
nexts_of tcs'.
Proof.
induction tcs as [|[]]; simpl; cases; simpl; auto; setoid_rewrite IHtcs; auto.
Qed.
Lemma reset_insts_of_In:
forall x tcs,
(
exists ck,
Is_reset_inst_in x ck tcs) <->
In x (
map fst (
inst_resets_of tcs)).
Proof.
induction tcs as [|[]];
simpl;
cases;
simpl;
intros.
-
setoid_rewrite Exists_nil.
split; [
intros (?&?)|
intros ?];
eauto using Cbase.
-
setoid_rewrite <-
IHtcs.
split;
intros (
ck&?);
exists ck;
try right;
eauto.
inversion_clear H as [??
Reset|];
try inv Reset;
auto.
-
setoid_rewrite <-
IHtcs;
split;
intros (
ck&?);
exists ck;
try right;
eauto.
inversion_clear H as [??
Reset|];
try inv Reset;
auto.
-
setoid_rewrite <-
IHtcs;
split.
+
intros (?&
H).
inversion_clear H as [??
Reset|];
try inv Reset;
eauto.
+
intros [
E|(
ck&?)];
subst.
*
exists c;
left;
constructor.
*
exists ck;
right;
auto.
-
setoid_rewrite <-
IHtcs;
split;
intros (
ck&?);
exists ck;
try right;
eauto.
inversion_clear H as [??
Reset|];
try inv Reset;
auto.
Qed.
Lemma insts_of_In:
forall x tcs,
Is_update_inst_in x tcs <->
In x (
map fst (
insts_of tcs)).
Proof.
induction tcs as [|[]];
simpl;
cases;
simpl.
all:
try now (
setoid_rewrite <-
IHtcs;
split;
try right;
auto;
inversion_clear 1
as [??
Last|];
try inv Last;
auto).
-
now setoid_rewrite Exists_nil.
-
setoid_rewrite <-
IHtcs;
split.
+
inversion_clear 1
as [??
Last|];
try inv Last;
auto.
+
intros [
E|?].
*
subst;
left;
constructor.
*
right;
auto.
Qed.
Lemma mems_of_states_fst:
forall {
A B C} (
lasts :
list (
ident * (
A *
B *
C))),
map fst (
mems_of_states lasts) =
map fst lasts.
Proof.
induction lasts; simpl; auto; f_equal; auto.
Qed.
IsVariable inductive
Inductive Is_variable_in_tc:
ident ->
trconstr ->
Prop :=
|
VarTcDef:
forall ck x e,
Is_variable_in_tc x (
TcDef ck x e)
|
VarTcStep:
forall x ck ckrs i xs f es,
In x xs ->
Is_variable_in_tc x (
TcUpdate ck ckrs (
UpdInst i xs f es)).
Global Hint Constructors Is_variable_in_tc :
stcdef.
Definition Is_variable_in (
x:
ident) (
tcs:
list trconstr) :
Prop :=
Exists (
Is_variable_in_tc x)
tcs.
Lemma Is_variable_in_tc_variables_tc:
forall tc x,
Is_variable_in_tc x tc <->
In x (
variables_tc tc).
Proof.
unfold variables.
intros *;
destruct tc;
simpl;
cases;
simpl;
split;
intro H;
try inv H;
auto.
-
constructor.
-
inv H0.
-
constructor;
auto.
Qed.
Corollary Is_variable_in_variables:
forall tcs x,
Is_variable_in x tcs <->
In x (
variables tcs).
Proof.
Definition is_variable_in_tc_b (
x:
ident) (
tc:
trconstr) :
bool :=
match tc with
|
TcDef _ x'
_ =>
ident_eqb x x'
|
TcUpdate _ _ (
UpdInst _ xs _ _) =>
existsb (
ident_eqb x)
xs
|
_ =>
false
end.
Fact Is_variable_in_tc_reflect:
forall x tc,
Is_variable_in_tc x tc <->
is_variable_in_tc_b x tc =
true.
Proof.
Lemma Is_variable_in_tc_dec:
forall x tc,
{
Is_variable_in_tc x tc } + { ~
Is_variable_in_tc x tc }.
Proof.
Lemma not_Is_variable_in_cons:
forall x tc tcs,
~
Is_variable_in x (
tc ::
tcs)
<-> ~
Is_variable_in_tc x tc /\ ~
Is_variable_in x tcs.
Proof.
split.
- intro Hndef; split; intro His_def;
eapply Hndef; now constructor.
- intros [Hdef_tc Hdef_tcs] Hdef_all.
inv Hdef_all; eauto.
Qed.
Lemma s_ins_not_var {
prefs}:
forall (
s: @
system prefs)
x,
InMembers x s.(
s_in) ->
~
Is_variable_in x s.(
s_tcs).
Proof.
IsLast inductive
Inductive Is_update_last_in_tc:
ident ->
trconstr ->
Prop :=
|
LastTcLast:
forall x ck ckrs e,
Is_update_last_in_tc x (
TcUpdate ck ckrs (
UpdLast x e)).
Definition Is_update_last_in (
x :
ident) (
tcs :
list trconstr) :=
Exists (
Is_update_last_in_tc x)
tcs.
Lemma not_Is_update_last_in_cons:
forall x tc tcs,
~
Is_update_last_in x (
tc ::
tcs) <-> ~
Is_update_last_in_tc x tc /\ ~
Is_update_last_in x tcs.
Proof.
split;
intros HH.
-
split;
intro;
apply HH;
unfold Is_update_last_in;
intuition.
-
destruct HH;
inversion_clear 1;
intuition.
Qed.
Lemma last_of_In:
forall x tc,
Is_update_last_in_tc x tc <->
In x (
map fst (
lasts_of [
tc])).
Proof.
destruct tc;
simpl;
cases;
simpl;
split;
intros H;
inv H;
auto using Is_update_last_in_tc.
inv H0.
Qed.
Lemma lasts_of_In:
forall x tcs,
Is_update_last_in x tcs <->
In x (
map fst (
lasts_of tcs)).
Proof.
induction tcs as [|[]];
simpl;
cases;
simpl.
all:
try now (
setoid_rewrite <-
IHtcs;
split;
try right;
auto;
inversion_clear 1
as [??
Last|];
try inv Last;
auto).
-
now setoid_rewrite Exists_nil.
-
setoid_rewrite <-
IHtcs;
split.
+
inversion_clear 1
as [??
Last|];
try inv Last;
auto.
+
intros [
E|?].
*
subst;
left;
constructor.
*
right;
auto.
Qed.
Definition is_update_last_in_tc_b (
x:
ident) (
tc:
trconstr) :
bool :=
match tc with
|
TcUpdate _ _ (
UpdLast y _) =>
ident_eqb x y
|
_ =>
false
end.
Definition is_update_last_in_b (
x:
ident) (
tcs:
list trconstr) :
bool :=
existsb (
is_update_last_in_tc_b x)
tcs.
Fact Is_update_last_in_tc_reflect:
forall x tc,
Is_update_last_in_tc x tc <->
is_update_last_in_tc_b x tc =
true.
Proof.
destruct tc;
simpl;
cases;
simpl;
split;
try discriminate;
try now inversion 1.
-
inversion_clear 1;
apply ident_eqb_refl.
-
rewrite ident_eqb_eq;
intro;
subst;
constructor.
Qed.
Corollary Is_update_last_in_reflect:
forall x tcs,
Is_update_last_in x tcs <->
is_update_last_in_b x tcs =
true.
Proof.
Lemma Is_update_last_in_dec:
forall x tcs,
{
Is_update_last_in x tcs } + { ~
Is_update_last_in x tcs }.
Proof.
Lemma not_Is_update_last_in_tc_TcLast:
forall y x ck ckrs le,
~
Is_update_last_in_tc y (
TcUpdate ck ckrs (
UpdLast x le)) ->
x <>
y.
Proof.
Lemma s_ins_not_last {
prefs}:
forall (
s: @
system prefs)
x,
InMembers x s.(
s_in) ->
~
Is_update_last_in x s.(
s_tcs).
Proof.
Lemma Last_with_reset_in_Is_update_last_in:
forall tcs s rst,
Last_with_reset_in s rst tcs ->
Is_update_last_in s tcs.
Proof.
induction 1 as [?? Last|].
- inv Last; left; constructor.
- right; auto.
Qed.
IsNext inductive
Inductive Is_update_next_in_tc:
ident ->
trconstr ->
Prop :=
|
NextTcNext:
forall x ck ckrs e,
Is_update_next_in_tc x (
TcUpdate ck ckrs (
UpdNext x e)).
Definition Is_update_next_in (
x :
ident) (
tcs :
list trconstr) :=
Exists (
Is_update_next_in_tc x)
tcs.
Lemma not_Is_update_next_in_cons:
forall x tc tcs,
~
Is_update_next_in x (
tc ::
tcs) <-> ~
Is_update_next_in_tc x tc /\ ~
Is_update_next_in x tcs.
Proof.
split;
intros HH.
-
split;
intro;
apply HH;
unfold Is_update_next_in;
intuition.
-
destruct HH;
inversion_clear 1;
intuition.
Qed.
Lemma next_of_In:
forall x tc,
Is_update_next_in_tc x tc <->
In x (
map fst (
nexts_of [
tc])).
Proof.
destruct tc;
simpl;
cases;
simpl;
split;
intros H;
inv H;
auto using Is_update_next_in_tc.
inv H0.
Qed.
Lemma nexts_of_In:
forall x tcs,
Is_update_next_in x tcs <->
In x (
map fst (
nexts_of tcs)).
Proof.
induction tcs as [|[]];
simpl;
cases;
simpl.
all:
try now (
setoid_rewrite <-
IHtcs;
split;
try right;
auto;
inversion_clear 1
as [??
Next|];
try inv Next;
auto).
-
now setoid_rewrite Exists_nil.
-
setoid_rewrite <-
IHtcs;
split.
+
inversion_clear 1
as [??
Next|];
try inv Next;
auto.
+
intros [
E|?].
*
subst;
left;
constructor.
*
right;
auto.
Qed.
Definition is_update_next_in_tc_b (
x:
ident) (
tc:
trconstr) :
bool :=
match tc with
|
TcUpdate _ _ (
UpdNext y _) =>
ident_eqb x y
|
_ =>
false
end.
Definition is_update_next_in_b (
x:
ident) (
tcs:
list trconstr) :
bool :=
existsb (
is_update_next_in_tc_b x)
tcs.
Fact Is_update_next_in_tc_reflect:
forall x tc,
Is_update_next_in_tc x tc <->
is_update_next_in_tc_b x tc =
true.
Proof.
destruct tc;
simpl;
cases;
simpl;
split;
try discriminate;
try now inversion 1.
-
inversion_clear 1;
apply ident_eqb_refl.
-
rewrite ident_eqb_eq;
intro;
subst;
constructor.
Qed.
Corollary Is_update_next_in_reflect:
forall x tcs,
Is_update_next_in x tcs <->
is_update_next_in_b x tcs =
true.
Proof.
Lemma Is_update_next_in_dec:
forall x tcs,
{
Is_update_next_in x tcs } + { ~
Is_update_next_in x tcs }.
Proof.
Lemma not_Is_update_next_in_tc_TcNext:
forall y x ck ckrs le,
~
Is_update_next_in_tc y (
TcUpdate ck ckrs (
UpdNext x le)) ->
x <>
y.
Proof.
Lemma s_ins_not_next {
prefs}:
forall (
s: @
system prefs)
x,
InMembers x s.(
s_in) ->
~
Is_update_next_in x s.(
s_tcs).
Proof.
Lemma Next_with_reset_in_Is_update_next_in:
forall tcs s rst,
Next_with_reset_in s rst tcs ->
Is_update_next_in s tcs.
Proof.
induction 1 as [?? Next|].
- inv Next; left; constructor.
- right; auto.
Qed.
IsResetLast inductive
Lemma not_Is_reset_state_in_cons:
forall x ck tc tcs,
~
Is_reset_state_in x ck (
tc ::
tcs) <-> ~
Is_reset_state_in_tc x ck tc /\ ~
Is_reset_state_in x ck tcs.
Proof.
split;
intros HH.
-
split;
intro;
apply HH;
unfold Is_reset_state_in;
intuition.
-
destruct HH;
inversion_clear 1;
intuition.
Qed.
Lemma not_Is_reset_state_in_cons':
forall x tc tcs,
~ (
exists ck,
Is_reset_state_in x ck (
tc ::
tcs)) <-> ~ (
exists ck,
Is_reset_state_in_tc x ck tc) /\ ~ (
exists ck,
Is_reset_state_in x ck tcs).
Proof.
split;
intros HH.
-
split;
intros (?&
H);
apply HH;
unfold Is_reset_state_in;
eauto.
-
destruct HH;
intros (?&
HH);
inversion_clear HH;
eauto.
Qed.
Lemma reset_state_of_In:
forall x tc,
(
exists ck,
Is_reset_state_in_tc x ck tc) <->
In x (
state_resets_of [
tc]).
Proof.
destruct tc;
simpl;
cases;
simpl; (
split; [
intros (?&
H)|
intro H]);
inv H;
eauto using Is_reset_state_in_tc.
inv H0.
Qed.
Lemma reset_states_of_In:
forall tcs x,
(
exists ck,
Is_reset_state_in x ck tcs) <->
In x (
state_resets_of tcs).
Proof.
induction tcs as [|[]];
simpl;
cases;
simpl;
intros.
-
setoid_rewrite Exists_nil.
split; [
intros (?&?)|
intros ?];
eauto using Cbase.
-
setoid_rewrite <-
IHtcs.
split;
intros (
ck&?);
exists ck;
try right;
eauto.
inversion_clear H as [??
Reset_State|];
try inv Reset_State;
auto.
-
setoid_rewrite <-
IHtcs;
split.
+
intros (?&
H).
inversion_clear H as [??
Reset_State|];
try inv Reset_State;
eauto.
+
intros [
E|(
ck&?)];
subst.
*
exists c;
left;
constructor.
*
exists ck;
right;
auto.
-
setoid_rewrite <-
IHtcs;
split;
intros (
ck&?);
exists ck;
try right;
eauto.
inversion_clear H as [??
Reset_State|];
try inv Reset_State;
auto.
-
setoid_rewrite <-
IHtcs;
split;
intros (
ck&?);
exists ck;
try right;
eauto.
inversion_clear H as [??
Reset_State|];
try inv Reset_State;
auto.
Qed.
Definition is_reset_state_in_tc_b (
x:
ident) (
ck:
clock) (
tc:
trconstr) :
bool :=
match tc with
|
TcReset ck' (
ResState y _ _) =>
ident_eqb x y &&
clock_eq ck ck'
|
_ =>
false
end.
Definition is_reset_state_in_b (
x:
ident) (
ck:
clock) (
tcs:
list trconstr) :
bool :=
existsb (
is_reset_state_in_tc_b x ck)
tcs.
Fact Is_reset_state_in_tc_reflect:
forall x ck tc,
Is_reset_state_in_tc x ck tc <->
is_reset_state_in_tc_b x ck tc =
true.
Proof.
Corollary Is_reset_state_in_reflect:
forall x ck tcs,
Is_reset_state_in x ck tcs <->
is_reset_state_in_b x ck tcs =
true.
Proof.
Lemma Is_reset_state_in_dec:
forall x ck tcs,
{
Is_reset_state_in x ck tcs } + { ~
Is_reset_state_in x ck tcs }.
Proof.
Lemma not_Is_reset_state_in_tc_TcReset_State:
forall y x ck ty ro,
~ (
exists ck',
Is_reset_state_in_tc y ck' (
TcReset ck (
ResState x ty ro))) ->
x <>
y.
Proof.
Lemma s_ins_not_reset_state {
prefs}:
forall (
s: @
system prefs)
x ck,
InMembers x s.(
s_in) ->
~
Is_reset_state_in x ck s.(
s_tcs).
Proof.
IsDefined inductive
Inductive Is_defined_in_tc:
ident ->
trconstr ->
Prop :=
|
DefTcDef:
forall x ck e,
Is_defined_in_tc x (
TcDef ck x e)
|
DefTcLast:
forall x ck ckrs e,
Is_defined_in_tc x (
TcUpdate ck ckrs (
UpdLast x e))
|
DefTcInst:
forall x ck ckrs i xs f es,
In x xs ->
Is_defined_in_tc x (
TcUpdate ck ckrs (
UpdInst i xs f es)).
Global Hint Constructors Is_defined_in_tc :
stcdef.
Definition Is_defined_in (
x:
ident) (
tcs:
list trconstr) :
Prop :=
Exists (
Is_defined_in_tc x)
tcs.
Lemma Is_defined_Is_variable_Is_last_in_tc:
forall tc x,
Is_defined_in_tc x tc <->
Is_variable_in_tc x tc \/
Is_update_last_in_tc x tc.
Proof.
Lemma Is_defined_Is_variable_Is_last_in:
forall tcs x,
Is_defined_in x tcs <->
Is_variable_in x tcs \/
Is_update_last_in x tcs.
Proof.
Corollary Is_variable_in_Is_defined_in:
forall x tcs,
Is_variable_in x tcs ->
Is_defined_in x tcs.
Proof.
Corollary Is_last_in_Is_defined_in:
forall x tcs,
Is_update_last_in x tcs ->
Is_defined_in x tcs.
Proof.
Lemma Is_variable_in_tc_Is_defined_in_tc:
forall x tc,
Is_variable_in_tc x tc ->
Is_defined_in_tc x tc.
Proof.
destruct tc; inversion_clear 1; auto with stcdef.
Qed.
Global Hint Resolve Is_variable_in_Is_defined_in Is_last_in_Is_defined_in Is_variable_in_tc_Is_defined_in_tc :
stcdef.
Lemma s_ins_not_def {
prefs}:
forall (
s: @
system prefs)
x,
InMembers x s.(
s_in) ->
~
Is_defined_in x s.(
s_tcs).
Proof.
Lemma not_Is_defined_in_tc_TcDef:
forall y x ck e,
~
Is_defined_in_tc y (
TcDef ck x e) ->
x <>
y.
Proof.
Lemma not_Is_defined_in_cons:
forall x tc tcs,
~
Is_defined_in x (
tc ::
tcs)
<-> ~
Is_defined_in_tc x tc /\ ~
Is_defined_in x tcs.
Proof.
split.
- intro Hndef; split; intro His_def;
eapply Hndef; now constructor.
- intros [Hdef_tc Hdef_tcs] Hdef_all.
inv Hdef_all; eauto.
Qed.
Definition defined_tc (
tc:
trconstr):
list ident :=
match tc with
|
TcDef _ x _ => [
x]
|
TcUpdate _ _ (
UpdLast x _) => [
x]
|
TcUpdate _ _ (
UpdInst _ xs _ _) =>
xs
|
_ => []
end.
Definition defined :=
flat_map defined_tc.
Lemma Is_defined_in_defined_tc:
forall x tc,
Is_defined_in_tc x tc <->
In x (
defined_tc tc).
Proof.
destruct tc;
simpl;
cases;
simpl;
split;
try inversion_clear 1;
subst;
auto using Is_defined_in_tc;
try contradiction.
Qed.
Lemma Is_defined_in_defined:
forall x tcs,
Is_defined_in x tcs <->
In x (
defined tcs).
Proof.
Lemma system_output_defined_in_tcs {
prefs}:
forall (
s: @
system prefs)
x,
In x (
map fst s.(
s_out)) ->
Is_defined_in x s.(
s_tcs).
Proof.
Lemma Is_defined_in_In:
forall x tcs,
Is_defined_in x tcs ->
exists tc,
In tc tcs /\
Is_defined_in_tc x tc.
Proof.
induction tcs as [|
tc].
now inversion 1.
inversion_clear 1
as [? ?
Hdef|? ?
Hex].
-
exists tc;
split;
auto with datatypes.
-
apply Exists_exists in Hex as (
tc' &
Hin &
Hdef).
exists tc';
split;
auto with datatypes.
Qed.
Lemma s_defined {
prefs} :
forall (
s: @
system prefs),
Permutation.Permutation (
defined (
s_tcs s)) (
variables (
s_tcs s) ++
map fst (
lasts_of (
s_tcs s))).
Proof.
Lemma s_nodup_variables_lasts_nexts {
prefs} :
forall (
s: @
system prefs),
NoDup (
variables (
s_tcs s) ++
map fst (
s_lasts s ++
s_nexts s)).
Proof.
Lemma s_nodup_defined {
prefs} :
forall (
s: @
system prefs),
NoDup (
defined (
s_tcs s)).
Proof.
Lemma incl_defined_lasts:
forall tcs,
incl (
map fst (
lasts_of tcs)) (
defined tcs).
Proof.
induction tcs;
intros ?
Hin;
simpl in *; [
inv Hin|].
apply in_app.
destruct a;
simpl in *;
cases;
simpl in *;
auto.
destruct Hin;
auto.
Qed.
Lemma nodup_defined_nodup_lasts:
forall tcs,
NoDup (
defined tcs) ->
NoDup (
lasts_of tcs).
Proof.
induction tcs;
intros;
simpl in *.
constructor.
cases;
simpl in *;
auto.
-
inv H;
auto.
-
inv H;
constructor;
auto.
intro Hin.
apply H2,
incl_defined_lasts;
auto.
eapply in_map_iff.
exists (
i,
typeofc c0);
eauto.
-
apply NoDup_app_r in H;
auto.
Qed.
Lemma defined_app:
forall tcs tcs',
defined (
tcs ++
tcs') =
defined tcs ++
defined tcs'.
Proof.
unfold defined.
induction tcs as [|[]];
simpl;
intros;
auto with datatypes.
-
rewrite <-
app_assoc;
f_equal;
auto.
Qed.
IsSystem inductive
Inductive Is_system_in_tc :
ident ->
trconstr ->
Prop :=
|
Is_system_inTcUpdate:
forall s ck ckrs ys f es,
Is_system_in_tc f (
TcUpdate ck ckrs (
UpdInst s ys f es))
|
Is_system_inTcReset:
forall s ck f,
Is_system_in_tc f (
TcReset ck (
ResInst s f)).
Definition Is_system_in (
f:
ident) (
tcs:
list trconstr) :
Prop :=
Exists (
Is_system_in_tc f)
tcs.
Lemma not_Is_system_in_cons:
forall b tc tcs,
~
Is_system_in b (
tc ::
tcs) <-> ~
Is_system_in_tc b tc /\ ~
Is_system_in b tcs.
Proof.
split;
intro HH.
-
split;
intro;
apply HH;
unfold Is_system_in;
intuition.
-
destruct HH;
inversion_clear 1;
intuition.
Qed.
Lemma steps_iresets_of_Is_system_in:
forall tcs b,
Is_system_in b tcs <->
In b (
map snd (
insts_of tcs ++
inst_resets_of tcs)).
Proof.
induction tcs as [|[]];
simpl;
cases;
simpl.
all:
try now (
setoid_rewrite <-
IHtcs;
split;
try (
right;
auto);
inversion_clear 1
as [??
IsSystem|];
auto;
inv IsSystem).
-
split;
try contradiction;
inversion 1.
-
split;
rewrite map_app,
in_app;
simpl.
+
inversion_clear 1
as [??
IsSystem|??
Systems];
try inv IsSystem;
auto.
apply IHtcs in Systems.
rewrite map_app,
in_app in Systems;
destruct Systems;
auto.
+
intros [?|[?|?]].
*
right;
apply IHtcs;
rewrite map_app,
in_app;
auto.
*
subst;
left;
constructor.
*
right;
apply IHtcs;
rewrite map_app,
in_app;
auto.
-
split;
rewrite map_app,
in_app;
simpl.
+
inversion_clear 1
as [??
IsSystem|??
Systems];
try inv IsSystem;
auto.
apply IHtcs in Systems.
rewrite map_app,
in_app in Systems;
destruct Systems;
auto.
+
intros [?|[?|?]].
*
subst;
left;
constructor.
*
right;
apply IHtcs;
rewrite map_app,
in_app;
auto.
*
right;
apply IHtcs;
rewrite map_app,
in_app;
auto.
Qed.
End STCSYNTAX.
Module StcSyntaxFun
(
Ids :
IDS)
(
Op :
OPERATORS)
(
OpAux :
OPERATORS_AUX Ids Op)
(
Cks :
CLOCKS Ids Op OpAux)
(
CESyn :
CESYNTAX Ids Op OpAux Cks)
<:
STCSYNTAX Ids Op OpAux Cks CESyn.
Include STCSYNTAX Ids Op OpAux Cks CESyn.
End StcSyntaxFun.