Require Import InteractionSemantics GlobDefs Footprint Injections GAST ETrace GlobUSim NPSemantics GlobSim GDefLemmas Coqlib Maps List Lia.
Ltac Hsimpl:=
repeat match goal with
|
H1:?
a,
H2:?
a->?
b|-
_=>
specialize (
H2 H1)
|
H:
_/\
_|-
_=>
destruct H
|
H:
exists _,
_|-
_=>
destruct H
end.
Ltac Esimpl:=
repeat match goal with
|
H:
_|-
_/\
_=>
split
|
H:
_|-
exists _,
_=>
eexists
end.
Ltac clear_get:=
repeat (
rewrite Maps.PMap.gsspec in *;(
destruct Coqlib.peq;
subst;
try contradiction;
simpl in *;
subst)).
Ltac clear_set:=
repeat (
rewrite Maps.PMap.set2 in *;(
destruct Coqlib.peq;
subst;
try contradiction;
simpl in *;
subst)).
Ltac solv_thread:=
repeat
match goal with
|
H:
ThreadPool.update _ _ _ _ |-
_ =>
Coqlib.inv H
|
H:
CallStack.update _ _ _ |-
_ =>
Coqlib.inv H
|
H:
ThreadPool.halted _ _ |-
_ =>
Coqlib.inv H
end;
unfold ThreadPool.get_top,
ThreadPool.pop,
ThreadPool.get_cs,
ThreadPool.push,
ThreadPool.valid_tid ,
CallStack.pop,
CallStack.top,
CallStack.is_emp,
CallStack.emp_cs in *;
simpl in *;
subst;
repeat (
rewrite Maps.PMap.gsspec in *;(
destruct Coqlib.peq;
subst;
try contradiction;
simpl in *;
subst));
repeat
match goal with
H:
context[
match ?
x with _ =>
_ end] |-
_ =>
destruct x eqn:?;
try (
inversion H;
fail)
|
H:
Some _ =
Some _ |-
_ =>
inversion H;
clear H;
subst
|
H:?
P = ?
Q,
H1:
context [ ?
P ] |-
_ =>
rewrite H in H1
|
H:?
P = ?
Q |-
context [ ?
P ] =>
rewrite H
end;
simpl in *;
GDefLemmas.solv_eq;
eauto;
clear_set;
simpl in *.
Section thdp.
Definition is_active {
GE:
GlobEnv.t} (
thdp: @
ThreadPool.t GE) (
t:
tid) :
nat :=
match ThreadPool.get_cs thdp t with
|
None => 0%
nat
|
Some nil => 0%
nat
|
Some (
_ ::
_) => 1%
nat
end.
Program Fixpoint count_rec {
GE:
GlobEnv.t} (
thdp: @
ThreadPool.t GE) (
cur:
tid)
{
measure (
Pos.to_nat cur)} :
nat :=
match cur with
| 1%
positive =>
is_active thdp cur
|
_ =>
is_active thdp cur + (
count_rec thdp (
Pos.pred cur))
end.
Next Obligation.
Definition count {
GE:
GlobEnv.t} (
thdp: @
ThreadPool.t GE):
nat :=
count_rec thdp (
ThreadPool.next_tid thdp).
Lemma count_rec_succ:
forall GE (
thdp: @
ThreadPool.t GE)
t,
count_rec thdp (
Pos.succ t) = (
is_active thdp (
Pos.succ t) + (
count_rec thdp t))%
nat.
Proof.
Lemma pop_emp_count_decr:
forall GE (
thdp: @
ThreadPool.t GE)
t thdp',
ThreadPool.inv thdp ->
ThreadPool.pop thdp t =
Some thdp' ->
ThreadPool.halted thdp'
t ->
count thdp =
S (
count thdp').
Proof.
Lemma upd_count_eq':
forall i GE (
thdp: @
ThreadPool.t GE)
t thdp'
c,
ThreadPool.inv thdp ->
ThreadPool.update thdp t c thdp' ->
count_rec thdp i=
count_rec thdp'
i.
Proof.
Lemma upd_count_eq:
forall GE (
thdp: @
ThreadPool.t GE)
t thdp'
c,
ThreadPool.inv thdp ->
ThreadPool.update thdp t c thdp' ->
count thdp =
count thdp'.
Proof.
End thdp.
Section simetr.
Variable GE:
GlobEnv.t.
Hypothesis wdge:
GlobEnv.wd GE.
Inductive sw_list :
nat->@
ProgConfig GE->
Prop:=
|
sw_0:
forall pc,
sw_list 0
pc
|
sw_1:
forall i pc pc',
np_step pc sw FP.emp pc'->
sw_list i pc'->
sw_list (
S i)
pc.
Definition active_thread_num :=
fun pc => @
count GE pc.(
thread_pool).
Lemma active_thread_num_exists:
forall pc,
ThreadPool.inv pc.(
thread_pool)->
exists i,
active_thread_num pc =
i.
Proof.
intros. eexists;eauto. Qed.
Lemma active_thread_num_dec:
forall pc pc',
ThreadPool.inv pc.(
thread_pool)->
atom_bit pc =
O->
np_step pc sw FP.emp pc'->
active_thread_num pc =
S (
active_thread_num pc').
Proof.
Lemma active_thread_num_eq:
forall pc pc',
ThreadPool.inv pc.(
thread_pool)->
atom_bit pc =
I->
np_step pc sw FP.emp pc'->
active_thread_num pc =
active_thread_num pc'.
Proof.
Lemma sw_time_limit:
forall pc,
ThreadPool.inv pc.(
thread_pool)->
@
atom_bit GE pc =
O->
forall j,
sw_list j pc->
(
j <=
active_thread_num pc)%
nat.
Proof.
CoInductive Sdiverge :@
ProgConfig GE->
Prop:=
|
SDiverge:
forall pc fp pc'
o,
o =
tau \/
o =
sw->
np_step pc o fp pc'->
Sdiverge pc'->
Sdiverge pc.
CoInductive SWdiverge:@
ProgConfig GE->
Prop:=
|
SWDiverge:
forall pc fp pc',
np_step pc sw fp pc'->
SWdiverge pc'->
SWdiverge pc.
Lemma SWdiverge_swlist_i:
forall i pc ,
SWdiverge pc->
sw_list i pc.
Proof.
induction i.
intros.
constructor.
intros.
inversion H;
subst.
apply IHi in H1.
econstructor 2;
eauto.
enough(
fp=
FP.emp);
try congruence.
inversion H0;
auto.
Qed.
Lemma thdp_inv_not_swdiverge:
forall pc,
ThreadPool.inv pc.(
thread_pool)->
~
SWdiverge pc.
Proof.
Lemma Sdiverge_inv:
forall pc,
ThreadPool.inv pc.(
thread_pool)->
Sdiverge pc->
exists pc'
fp pc'',
sw_star np_step pc pc'/\
np_step pc'
tau fp pc'' /\
ThreadPool.inv pc''.(
thread_pool) /\
Sdiverge pc''.
Proof.
Lemma Sdiverge_sound:
forall pc,
ThreadPool.inv pc.(
thread_pool) ->
Sdiverge pc->
silent_diverge np_step pc.
Proof.
cofix.
intros.
apply Sdiverge_inv in H0;
auto.
Hsimpl.
econstructor;
eauto.
Qed.
Lemma sw_star_cons_Sdiverge:
forall pc pc',
sw_star np_step pc pc'->
Sdiverge pc'->
Sdiverge pc.
Proof.
induction 1;intros. auto.
econstructor;eauto.
Qed.
Lemma Sdiverge_exists:
forall pc,
silent_diverge np_step pc->
Sdiverge pc.
Proof.
intros.
inversion H;
clear H;
subst.
revert pc s'
fp'
s''
H0 H1 H2.
cofix.
intros.
inversion H0;
subst.
{
inversion H2;
subst.
inversion H;
subst.
econstructor 1
with(
o:=
tau);
eauto.
econstructor 1
with(
o:=
tau);
eauto.
}
{
econstructor ;
eauto.
}
Qed.
Inductive non_evt_plus {
State:
Type}(
step:
State->
glabel->
FP.t->
State->
Prop):
State ->
FP.t ->
State ->
Prop :=
|
ne_plus1:
forall s o fp s',
o =
tau \/
o =
sw ->
step s o fp s'->
non_evt_plus step s fp s'
|
ne_star_step:
forall s1 o fp1 s2 fp2 s3,
o =
tau \/
o =
sw ->
step s1 o fp1 s2 ->
non_evt_plus step s2 fp2 s3 ->
non_evt_plus step s1 (
FP.union fp1 fp2)
s3.
CoInductive Pdiverge (
pc:@
ProgConfig GE):
Prop:=
|
PDiverge:
forall fp pc',
non_evt_plus np_step pc fp pc'->
Pdiverge pc'->
Pdiverge pc.
Lemma Pdiverge_sound:
forall pc,
Pdiverge pc ->
Sdiverge pc.
Proof.
inversion 1;subst. clear H.
revert pc fp pc' H0 H1. cofix. intros.
inversion H0;subst.
{
inversion H1.
econstructor;eauto.
}
{
econstructor;eauto.
}
Qed.
Lemma Pdiverge_exists:
forall pc,
Sdiverge pc->
Pdiverge pc.
Proof.
cofix;inversion 1;subst. econstructor;eauto. econstructor;eauto. Qed.
CoInductive SEtr (
pc:@
ProgConfig GE) :
behav->
Prop:=
|
SEtr_done :
forall fp pc',
non_evt_star np_step pc fp pc' ->
final_state pc' ->
SEtr pc Behav_done
|
SEtr_abort :
forall fp pc',
non_evt_star np_step pc fp pc' ->
np_abort pc' ->
SEtr pc Behav_abort
|
SEtr_diverge :
Sdiverge pc ->
SEtr pc Behav_diverge
|
SEtr_cons:
forall fp pc'
v pc''
b,
non_evt_star np_step pc fp pc'->
np_step pc' (
evt v)
FP.emp pc''->
SEtr pc''
b->
SEtr pc (
Behav_cons v b).
Lemma non_evt_star_star{
State:
Type}:
forall step s fp s',
@
non_evt_star State step s fp s'->
exists l,
star step s l fp s'.
Proof.
induction 1.
eexists. constructor.
destruct IHnon_evt_star.
destruct H;eexists;econstructor;eauto.
Qed.
Lemma GE_mod_wd_npstar_tp_inv:
forall ge pc l fp pc',
star (@
np_step ge)
pc l fp pc' ->
GlobEnv.wd ge ->
ThreadPool.inv pc.(
thread_pool) ->
ThreadPool.inv pc'.(
thread_pool).
Proof.
Lemma non_evt_star_thdp_inv:
forall ge pc fp pc',
GlobEnv.wd ge->
ThreadPool.inv pc.(
thread_pool)->
non_evt_star (@
np_step ge)
pc fp pc'->
ThreadPool.inv pc'.(
thread_pool).
Proof.
Lemma SEtr_sound:
forall pc b,
ThreadPool.inv pc.(
thread_pool)->
SEtr pc b->
Etr np_step np_abort final_state pc b.
Proof.
Lemma SEtr_exists:
forall pc b,
Etr np_step np_abort final_state pc b->
SEtr pc b.
Proof.
cofix.
intros.
inversion H;
subst;
econstructor;
eauto.
eapply Sdiverge_exists;
eauto.
Qed.
End simetr.