Require Import
Utf8 Classical
Coqlib Ast Maps Mem Op
Globalenvs Events Values.
Require Import
Utils Emem Permissions TSOMemoryMachine
INJECT RTLinject.
Require Import
TSOmachine Simulations.
Section TSOSEM.
Definition te_of_me (
me:
mem_event) :
Events.thread_event :=
match me with
|
MEwrite _ _ p v =>
Events.TEmem (
Events.MEwrite p Mint32 v)
|
MEread _ _ p v =>
Events.TEmem (
Events.MEread p Mint32 v)
|
MErmw _ p v i =>
Events.TEmem (
Events.MErmw p Mint32 v i)
|
MEalloc p i k =>
Events.TEmem (
Events.MEalloc p i k)
|
MEfree p k =>
Events.TEmem (
Events.MEfree p k)
|
MEperm _ =>
Events.TEtau
end.
Definition te_of_te (
ev:
thread_event) :
option Events.thread_event :=
match ev with
|
TEext e =>
Some (
Events.TEext e)
|
TEtso (
INJECT.TSOmem e) =>
Some (
te_of_me e)
|
TEend ReturnVoid
|
TEend FailEvent =>
Some (
Events.TEext Events.Efail)
|
TEstart fp v =>
Some (
Events.TEstart fp (
v::
nil))
|
TEexit =>
Some Events.TEexit
|
TEtso TSOfence =>
Some (
Events.TEmem Events.MEfence)
|
TEtso (
INJECT.TSOunbuf _)
|
TEbegin BeginLow
|
TEend (
ReturnEvent _)
|
TEtau =>
Some Events.TEtau
|
TEtso (
INJECT.TSObeginatomic)
|
TEtso (
INJECT.TSOendatomic _)
|
TEtso (
INJECT.TSOstart _)
|
TEato _
|
TEbegin BeginHigh =>
None
end.
Definition not_a_high_state (
st:
intra_state) :
bool :=
match st with
|
RIInjectState _ _ _ _ _ _ (
INJECT.NormalState _ is k) =>
match is with
|
Satomic _ _
|
Sloop _ |
Sbranch _ _ =>
false
|
_ =>
match in_atomic k with
|
Some _ =>
false
|
None =>
true
end
end
|
_ =>
true
end.
Inductive rtl_step' (
ge:
genv) :
intra_state →
Events.thread_event →
intra_state →
Prop :=
|
Rtl_step s e s'
te
(
STEP:
rtli_step ge s e s')
(
LOW:
not_a_high_state s)
(
TE:
Some te =
te_of_te e) :
rtl_step'
ge s te s'.
Ltac inv_step :=
match goal with
|
H :
step _ _ _ _ _ |-
_ =>
inversion H;
try (
subst;
clear H)
end.
Ltac sktau :=
match goal with
| [
H:
te_samekind ?
t Events.TEtau |-
_] =>
rewrite (
te_tau_samekind t H)
in *;
clear H
| [
H:
te_samekind ?
t ?
q |-
_] =>
let p :=
fresh in
destruct t as [
p|
p| | |? ?|? ?|? ? ?|];
try destruct p;
inversion H;
subst;
clear H
end.
Lemma rtli_receptive :
forall ge :
genv,
receptive(@
mklts thread_labels intra_state (
rtl_step'
ge)).
Proof.
intros ge.
intros l l'
s s'
STEP'
Hll.
simpl in *.
inv STEP'.
inv STEP;
try inv_step;
inv TE;
match goal with [
H:
atomic_statement_mem_event _ _ _ _ ?
l |-
_] =>
destruct l;
try now inversion H
|
_ =>
idtac end;
sktau;
try (
now inversion LOW);
try (
now eexists;
vauto);
try (
now eexists;
vauto;
econstructor;
vauto).
destruct res0;
clarify.
eexists;
vauto.
simpl in *;
intuition congruence.
eexists;
vauto.
apply Rtl_step with (
e :=
TEbegin BeginLow);
vauto.
intuition subst.
eexists;
vauto.
apply Rtl_step with (
e :=
TEtso (
INJECT.TSOmem (
MEread ap inbuf a v0)));
vauto.
intuition subst.
inv ASME;
eexists;
eapply Rtl_step with (
e :=
TEtso (
INJECT.TSOmem (
MErmw r p v1 _))).
(
econstructor;[|
congruence]).
eapply exec_atomic.
rewrite <-
H1.
vauto.
easy.
intuition.
easy.
easy.
Qed.
Ltac hpc :=
match goal with
|
H:
_ =
_,
K:
_ =
_ |-
_ =>
rewrite H in K;
inversion K;
subst;
clear K
|
H:
_ =
_,
K:
_ =
_ |-
_ =>
rewrite <-
H in K;
inversion K;
subst;
clear K
end.
Lemma map_vint_inj :
forall {
u v},
map Vint u =
map Vint v →
u =
v.
Proof.
induction u as [|a u]; intros [|b v]; trivial; inversion 1. f_equal. intuition.
Qed.
Lemma rtli_determinate :
forall ge :
genv,
determinate (@
mklts thread_labels intra_state (
rtl_step'
ge)).
Proof.
Hint Resolve atomic_statement_determinate @
atomic_statement_determinate_eq @
map_val_of_eval_eq
@
map_vint_inj.
intros ge u v v'
l l'
stepv stepv'.
simpl in *.
inv stepv.
inv STEP;
simpl in *;
clarify;
inv stepv';
inv STEP;
simpl in *;
try destruct sp;
clarify;
repeat hpc;
try (
by (
intuition (
repeat f_equal;
eauto);
simpl in *;
clarify));
(
inv_step;
inv_step;
simpl in *;
clarify;
discr;
repeat hpc;
intuition (
repeat (
eauto;
f_equal));
vauto);
eauto;
inv ASME;
inv ASME0;
simpl;
hpc;
intuition;
now inv H.
Qed.
Definition rtl_ge_init (
p:
program) (
ge:
genv) (
m:
Mem.mem) :
Prop :=
Genv.globalenv_initmem p ge Ast.low_mem_restr m.
Definition RtlInjectSem :
SEM.
Proof.
refine (
mkSEM _ _ _ rtl_ge_init (@
prog_main _ _) (@
Genv.find_symbol _)
rtl_step'
rtl_inject_init
_ rtli_receptive rtli_determinate).
intros ge s.
set (
P :=
exists l',
exists s',
rtl_step'
ge s l'
s').
destruct (
classic P)
as [
H|
H];
intuition.
left.
intros s'
l'
K.
elim H.
exists l';
exists s'.
assumption.
Defined.
End TSOSEM.
Section TRACES.
Require Traces.
Variable p :
program.
Variable args :
list val.
Variable t :
Traces.trace event.
Definition rtli_lts ge :=
mklts event_labels (
TSO.step RtlInjectSem ge).
Definition rtli_traces :
Prop :=
exists ge :
genv,
exists s :
TSO.state RtlInjectSem,
TSO.init RtlInjectSem p args ge s /\
Traces.traces (
rtli_lts ge)
s t.
End TRACES.
Section LOWSIM.
Variable ge :
genv.
Definition can_unbuffer (
tso:
tsomem) :
Prop :=
∀
tid bi buf,
tso.(
TSOMemoryMachine.buffers)
tid =
buf ++
bi ::
nil →
∃
m', ∃
e',
TSOMemoryMachine.buf_step tid tso.(
shared_mem)
bi e'
m'.
Definition progress (
s:
state) :
Prop :=
∀
tid st,
(
snd s) !
tid =
Some st →
∃
e, ∃
s',
astep ge s (
tid,
e::
nil)
s'
∧ (∀
bi,
e ≠
TEtso (
TSOunbuf bi))
∧
not_a_high_state st.
Definition wf_load (
s:
state) :
Prop :=
∀
tid,
match (
snd s) !
tid with
|
Some (
RIInjectState _ _ sp _ _ _ (
NormalState irs
(
Sload _ addr args _)
_)) =>
∀
p m v,
eval_addressing ge sp addr (
map irs args) =
Some (
Vptr p) →
flush tid ((
fst s).(
TSOMemoryMachine.buffers)
tid) (
fst s)
m →
load_ptr Mint32 m.(
MemoryMachine.mem_rtl)
p =
Some v →
wf_val v
|
_ =>
True
end.
Definition reachable (
i:
state) :
state →
Prop :=
fun s => ∃
tr,
trace ge i tr s.
Remark reachable_refl :
reflexive _ reachable.
Proof.
intros x.
exists nil.
constructor. Qed.
Remark reachable_trans:
transitive _ reachable.
Proof.
intros x y z (
tr1 &
H1) (
tr2 &
H2).
eexists.
eapply trace_app;
eauto.
Qed.
Definition can_write_and_free (
s:
state) :
Prop :=
∀
tid,
match (
snd s) !
tid with
|
Some (
RIInjectState _ _ sp _ _ _ (
NormalState irs
(
Sstore _ _ addr args src)
k)) =>
∀
p,
eval_addressing ge sp addr (
map irs args) =
Some (
Vptr p) →
(
fst s).(
TSOMemoryMachine.buffers)
tid =
empty_buffer →
load_ptr Mint32 (
fst s).(
MemoryMachine.mem_rtl)
p ≠
None
|
Some (
RIState _ c (
Some sp)
pc _) =>
∀
res,
c !
pc =
Some (
Ireturn res) →
(
fst s).(
TSOMemoryMachine.buffers)
tid =
empty_buffer →
∃
m',
free_ptr sp MObjStack (
fst s).(
MemoryMachine.mem_rtl) =
Some m'
∧
forall tid'
p v b,
(
fst s).(
TSOMemoryMachine.buffers)
tid' =
b ++
WBufItem p v ::
nil →
store_ptr Mint32 m'
p v ≠
None
|
_ =>
True
end.
Lemma may_store_may_load : ∀
m p v m',
store_ptr Mint32 m p v =
Some m' →
load_ptr Mint32 m p ≠
None.
Proof.
intros m p v m' H K.
pose proof (store_chunk_allocated_someD H).
pose proof (load_chunk_allocated_noneD K).
intuition.
Qed.
Lemma can_unbuffer_can_write_and_free i :
(∀
s,
reachable i s →
can_unbuffer (
fst s)) →
∀
s,
reachable i s →
progress s →
can_write_and_free s.
Proof.
intros SAFE (
m &
st)
REACH PROGRESS tid.
simpl.
case_eq (
st !
tid);
trivial.
intros ts Hst.
case_eq ts;
trivial.
intros stk c [
sp|]
pc rs Hts;
trivial.
intros res Hpc Bemp.
generalize (
PROGRESS tid).
intros P.
destruct (
P _ Hst)
as (
e &
ts' &
STEP &
TSO &
LOW).
inv STEP;
autorw'.
2:
eelim TSO;
reflexivity.
2:
inv AS1;
inv ST;
autorw'.
2:
inv AS1;
inv ST;
autorw'.
2:
inv AS1;
inv ST.
2:
inv AS1.
inv AS1.
inv ST;
autorw'.
eelim IS_not_mem;
reflexivity.
assert (
reachable i (
TSOMEM m (
upd m.(
TSOMemoryMachine.buffers)
tid (
FBufItem sp MObjStack ::
nil)),
st !
tid <- (
RIRetState stk (
rs res))))
as REACH'.
apply reachable_trans with (
m,
st).
assumption.
eexists ((
tid,
_::
nil)::
nil).
econstructor.
econstructor.
eapply astep_free.
eassumption.
reflexivity.
eapply intra_step_mem.
vauto.
destruct m.
vauto.
easy.
easy.
easy.
generalize (
SAFE _ REACH').
intros X.
edestruct (
X tid)
as (
M &
BS).
simpl.
rewrite upd_s.
rewrite app_nil_l.
reflexivity.
clear X.
simpl in *.
exists M.(
MemoryMachine.mem_rtl).
split.
destruct BS.
inv H.
simpl.
assumption.
intros tid'
p v b H K.
assert (
reachable i (
TSOMEM M (
upd (
upd (
TSOMemoryMachine.buffers m)
tid (
FBufItem sp MObjStack ::
nil))
tid empty_buffer),
st !
tid <- (
RIRetState stk (
rs res))))
as REACH''.
eapply reachable_trans.
apply REACH'.
destruct BS as (
e'' &
BS).
eexists ((
tid,
_::
nil)::
nil).
econstructor.
econstructor.
eapply astep_unbuf.
eapply tso_step_unbuf.
reflexivity.
rewrite upd_s.
rewrite app_nil_l.
reflexivity.
eassumption.
assert (
tid ≠
tid').
intros ->.
autorw'.
unfold empty_buffer in *.
app_inv.
generalize (
SAFE _ REACH'').
intros X.
edestruct (
X tid')
as (
M' &
BS').
simpl.
rewrite upd_o;
trivial.
rewrite upd_o;
trivial.
autorw'.
simpl in *.
destruct BS'
as (
ee &
BS').
inv BS'.
simpl in *.
autorw'.
intros stk c sp next rs edst is Hts.
case_eq is;
trivial.
intros irs stmt cont His.
case_eq stmt;
trivial.
intros release ap addr args dst Hstmt p EVAL Bemp K.
generalize (
PROGRESS tid).
intros P.
destruct (
P _ Hst)
as (
e &
ts' &
STEP &
TSO &
LOW).
inv STEP;
autorw'.
2:
eelim TSO;
reflexivity.
2:
inv AS1;
inv ST;
inv INJECT.
2:
inv AS1;
inv ST;
inv INJECT.
2:
inv AS1;
inv ST;
inv INJECT.
2:
inv AS1;
inv INJECT.
inv AS1.
inv ST;
inv INJECT;
eelim IS_not_mem;
reflexivity.
inv ST.
inv INJECT.
autorw'.
assert (∃
s',
reachable i s' ∧
(
fst s').(
MemoryMachine.mem_rtl) =
m.(
MemoryMachine.mem_rtl) ∧
(
fst s').(
TSOMemoryMachine.buffers)
tid =
WBufItem p (
irs dst) ::
nil)
as ONE.
eexists.
split.
apply reachable_trans with (
m,
st).
assumption.
eexists ((
tid,
_::
nil)::
nil).
econstructor.
econstructor.
eapply astep_free.
eassumption.
reflexivity.
eapply intra_step_mem.
vauto.
eassumption.
easy.
easy.
easy.
split;
simpl;
inv ES.
destruct release.
inv TM3.
reflexivity.
subst.
reflexivity.
simpl.
rewrite upd_s.
simpl in *.
autorw'.
destruct ONE as ((
s' &
st') &
REACH' &
MEM &
BUF).
generalize (
SAFE _ REACH').
intros X.
edestruct (
X tid)
as (
M &
BS).
autorw'.
rewrite app_nil_l.
reflexivity.
destruct BS as (
e &
BS).
destruct m.
inv BS.
simpl in *.
autorw'.
destruct s'
as ((
s' &
s'
d) & ?).
simpl in *.
clarify.
inv ES.
exploit may_store_may_load;
eauto.
Qed.
Inductive safe_buf t :
buffer →
MemoryMachine.mem →
Prop :=
|
SBnil m :
safe_buf t nil m
|
SBsnoc m buf bi m'
e
(
UNB:
TSOMemoryMachine.buf_step t m bi e m')
(
SB:
safe_buf t buf m')
:
safe_buf t (
buf ++
bi ::
nil)
m.
Lemma can_unbuffer_safe' {
i tid} :
(∀
s,
reachable i s →
can_unbuffer (
fst s)) →
∀
buf,
∀
m t,
reachable i (
m,
t) →
m.(
TSOMemoryMachine.buffers)
tid =
buf →
safe_buf tid buf m.(
shared_mem).
Proof.
intros SAFE.
refine (
rev_ind _ _ _).
vauto.
intros bi buf IH m t REACH EQB.
generalize (
SAFE _ REACH tid).
intros K.
destruct m as (
m &
B).
destruct (
K _ _ EQB)
as (
m' &
H).
generalize (
IH (
TSOMEM m' (
upd B tid buf))
t).
simpl in *.
destruct H as (
e' &
H).
intros F.
clear IH.
econstructor;
eauto.
apply F.
apply reachable_trans with (
TSOMEM m B,
t);
auto.
2:
apply upd_s.
eexists.
eapply trace_cons.
apply trace_nil.
eapply astep_unbuf.
vauto.
Qed.
Corollary can_unbuffer_safe i :
(∀
s,
reachable i s →
can_unbuffer (
fst s)) →
∀
s t,
reachable i (
s,
t) →
∀
tid,
safe_buf tid (
s.(
TSOMemoryMachine.buffers)
tid)
s.(
shared_mem).
Proof.
intros H s t H0 tid. eapply can_unbuffer_safe'; eauto. Qed.
Definition l_state :
Type := (
tso_state *
PTree.t intra_state)%
type.
Definition l_step :
l_state →
fullevent →
l_state →
Prop :=
TSO.step RtlInjectSem ge.
Inductive match_bi :
buf_item →
buffer_item →
Prop :=
|
MBIW p v
:
match_bi (
WBufItem p v) (
BufferedWrite p Mint32 v)
|
MBIA p i k
:
match_bi (
ABufItem p i k) (
BufferedAlloc p i k)
|
MBIF p k
:
match_bi (
FBufItem p k) (
BufferedFree p k)
.
Definition match_buf : (
thread_id →
buffer) →
buffers →
Prop :=
fun x y => ∀
t,
lift_forall_list match_bi (
rev (
x t)) (
y t).
Definition match_mem :
MemoryMachine.mem →
mem →
Prop :=
fun x y =>
MemoryMachine.mem_rtl x =
y.
Remark match_bi_abi {
a b m n t buf} :
match_bi a b →
match_mem m n →
safe_buf t (
buf ++
a ::
nil)
m →
forall {
n'},
apply_buffer_item b n =
Some n' →
∃
m',
unbuffer t (
m,
buf ++
a ::
nil) (
m',
buf)
∧
match_mem m'
n'
∧
safe_buf t buf m'
.
Proof.
inversion 1; subst; simpl; intros MEM SAFE n' U.
destruct m as (m & P); inv MEM.
inv SAFE; app_inv. inv UNB. simpl in U. autorw'.
eexists. split. vauto.
econstructor; eauto.
econstructor; eauto.
destruct m; inv MEM.
inv SAFE; app_inv. inv UNB. simpl in U. autorw'.
eexists. split. vauto. split; vauto.
destruct m; inv MEM.
inv SAFE; app_inv. inv UNB. simpl in U. autorw'.
eexists. split. vauto. split; vauto.
Qed.
Definition safe_tsomem :
tsomem →
Prop :=
fun M => ∀
t,
safe_buf t (
M.(
TSOMemoryMachine.buffers)
t)
M.(
shared_mem).
Definition safe_state :
state →
Prop :=
fun Mts =>
safe_tsomem (
fst Mts) ∧
progress Mts ∧
wf_load Mts ∧
can_write_and_free Mts.
Remark flush_ab {
a b t} :
match_buf a b →
forall {
m n},
match_mem m n →
safe_tsomem (
TSOMEM m a) →
forall {
n'},
apply_buffer (
b t)
n =
Some n' →
∃
m',
flush t (
a t)
m m'
∧
match_mem m'
n'
.
Proof.
intros BUF m n MEM SAFE.
generalize (
SAFE t).
simpl.
clear SAFE.
rewrite <- (
rev_involutive (
a t)).
generalize dependent m.
generalize dependent n.
generalize (
BUF t).
clear BUF.
generalize (
rev (
a t)).
generalize (
b t).
induction 1.
simpl.
intros ? ? ?
_ ?
K;
inv K.
eexists;
intuition eauto.
vauto.
simpl.
intros n m MEM SAFE n'
K.
case_eq (
apply_buffer_item y n);[
intros M'|];
intros Q;
autorw'.
simpl in K.
destruct (
match_bi_abi HEAD MEM SAFE Q)
as (
m' &
A &
B &
C).
destruct (
IHlift_forall_list _ _ B C _ K)
as (
m'' &
A' &
B').
clear IHlift_forall_list.
eexists.
split. 2:
apply B'.
vauto.
Qed.
Inductive match_state :
state →
l_state →
Prop :=
|
MS m m'
buf buf'
ts
(
MEM:
match_mem m m')
(
BUF:
match_buf buf buf')
:
match_state (
TSOMEM m buf,
ts) (
mktsostate buf'
m',
ts)
.
Definition match_ev :
thread_event →
fullevent →
Prop :=
fun te e =>
match te with
|
TEext f =>
e =
Evisible f
|
TEend ReturnVoid
|
TEend FailEvent =>
e =
Evisible Efail
|
TEbegin BeginHigh =>
False
|
_ =>
e =
Etau
end.
Definition progress' (
s:
state) :
Prop :=
∀
tid,
match (
snd s) !
tid with
|
Some (
RIInjectState stk c sp pc rs dst
(
NormalState irs (
Sload ap addr args res)
k)) =>
∀
p,
eval_addressing ge sp addr (
map irs args) =
Some (
Vptr p) →
wf_ptr p
∧ ∀
m'
perms,
flush tid ((
fst s).(
TSOMemoryMachine.buffers)
tid) (
fst s).(
shared_mem) (
MemoryMachine.MEM m'
perms) →
(
match ap with Local =>
readable_perm perms p tid
|
Global => ∀
t,
perms p =
HiddenBy t →
tid =
t end)
∧ (∃
v,
wf_val v ∧
if addr_in_buf p ((
fst s).(
TSOMemoryMachine.buffers)
tid)
then buf_load p ((
fst s).(
TSOMemoryMachine.buffers)
tid) =
Some v
else MemoryMachine.mem_step tid (
fst s) (
MEread ap false p v) (
fst s))
∧ (∀
x k, ¬
In (
FBufItem x k) ((
fst s).(
TSOMemoryMachine.buffers)
tid))
|
Some (
RIInjectState _ _ _ _ _ _
(
NormalState irs (
Satomicmem r cas args dst)
k)) =>
∃
instr, ∃
p, ∃
v,
atomic_statement_mem_event r cas (
map irs args)
v (
MErmw r p v instr)
∧
wf_rmw instr
∧
wf_ptr p
∧
load_ptr Mint32 (
fst s).(
MemoryMachine.mem_rtl)
p =
Some v ∧
wf_val v
∧ ∃
m',
store_ptr Mint32 (
fst s).(
MemoryMachine.mem_rtl)
p (
rmw_instr_semantics instr v) =
Some m'
∧ ∃
d', (
if r then release tid (
fst s).(
MemoryMachine.perms)
d'
else (
fst s).(
MemoryMachine.perms)=
d') ∧
d'
p =
empty_perm
|
Some (
RIInjectState stk c sp pc rs dst
(
NormalState irs (
Srequestperm rp addr args)
k)) =>
∀
p,
eval_addressing ge sp addr (
map irs args) =
Some (
Vptr p) →
∃
perm',
perm_step tid (
fst s).(
MemoryMachine.perms) (
PErequest rp p)
perm'
|
Some (
RIInjectState stk c sp pc rs dst
(
NormalState irs Srelease k)) =>
∃
perm',
perm_step tid (
fst s).(
MemoryMachine.perms)
PErelease perm'
|
Some (
RIInjectState stk c sp pc rs dst
(
NormalState irs (
Sstore released ap addr args src)
k)) =>
(∀
p,
eval_addressing ge sp addr (
map irs args) =
Some (
Vptr p) →
check_perm_store tid (
fst s).(
MemoryMachine.perms)
ap p ∧
wf_ptr p)
∧
if released then ∃
perm',
perm_step tid (
fst s).(
MemoryMachine.perms)
PErelease perm'
else True
|
Some (
RIInjectState stk c sp pc rs dst
(
NormalState irs Sfreeperm k)) =>
∃
perm',
perm_step tid (
fst s).(
MemoryMachine.perms)
PEfreeperm perm'
|
_ =>
True
end.
Remark progress_progress' (
s:
state) :
progress s →
progress'
s.
Proof.
intros P tid.
destruct s as (((
m &
perm) &
B) &
st).
simpl.
case_eq (
st !
tid). 2:
easy.
intros ts H.
generalize (
P _ _ H).
clear P.
intros (
e &
ts' &
STEP &
TSO &
LOW).
inv STEP;
try (
inv AS1;
try inv ST;
try inv INJECT;
autorw');
try (
eelim IS_not_mem;
reflexivity).
intros ? ?;
clarify.
inv ES.
case_eq (
addr_in_buf p (
B tid));
intros K;
autorw'.
intuition.
pose proof (
flush_preserves_perm H2);
simpl in *;
subst.
auto.
exists v.
intuition.
inv TM2;
split;
auto;
intros m'
perms H;
pose proof (
flush_preserves_perm H);
simpl in *;
subst;
intuition.
exists v.
intuition.
vauto.
exists v.
intuition.
vauto.
split.
intros ? ?;
clarify.
inv ES.
split;
assumption.
destruct released;
trivial.
inv ES.
inv TM3.
eexists;
eassumption.
intros ? ?;
clarify.
inv ES.
inv TM1.
eexists;
eauto.
inversion ASME; (
inv ES;
clarify;
try now (
destruct bi;
clarify));
(
eexists;
eexists;
eexists;
split;[
autorw';
eassumption|]).
inv TM2.
intuition.
eexists;
intuition eauto.
inv ES.
inv TM1.
eexists;
eauto.
inv ES.
inv TM1.
eexists;
eauto.
eelim TSO;
reflexivity.
Qed.
Lemma safe_not_stuck s tso st tid ts :
safe_state s →
match_state s (
tso,
st) →
st !
tid =
Some ts →
¬ ∀
ts'
ev, ¬
rtl_step'
ge ts ev ts'.
Proof.
destruct s as (
s &
st').
intros (
SAFE_MEM &
PROGRESS &
_)
MS'
Gtid K;
inv MS'.
destruct (
PROGRESS _ _ Gtid)
as (
s' &
e &
H &
TSO &
LOW).
inv H.
autorw'.
inv AS1.
inv ST;
try (
eelim IS_not_mem;
reflexivity);
clarify.
eelim K;
vauto.
eelim K;
vauto.
eelim K;
vauto.
eelim K;
vauto.
eelim K;
vauto.
eelim K;
vauto.
eelim K;
vauto.
eelim K;
vauto.
eelim K.
econstructor;
eauto.
eapply RTLI_return_external with (
res :=
res);
eauto.
reflexivity.
eelim K;
vauto.
eelim K;
vauto.
eelim K;
econstructor;
eauto.
eapply RTLI_inject_start_low;
eauto.
reflexivity.
eelim K;
econstructor;
eauto.
eapply RTLI_inject_start_low;
eauto.
reflexivity.
inv INJECT;
try (
eelim IS_not_mem;
reflexivity);
try now (
simpl in LOW;
clarify);
eelim K;
(
econstructor;
eauto; [
eapply RTLI_inject_step;
eauto ;
vauto |
reflexivity]).
inv INJECT.
eelim K.
econstructor;
eauto.
vauto.
reflexivity.
eelim K;
vauto.
eelim K;
vauto.
inv ST.
eelim K;
econstructor;
eauto.
eapply RTLI_fun_internal_alloc with (
sp :=
sp);
eauto.
reflexivity.
eelim K;
vauto.
inv INJECT;
try (
now simpl in LOW;
clarify;
autorw');
try (
eelim K;
(
econstructor;
eauto; [
eapply RTLI_inject_step;
eauto ;
vauto |
reflexivity])).
eelim TSO;
reflexivity.
inv AS1.
inv ST. 2:
inv INJECT.
autorw'.
eelim K.
vauto.
inv AS1.
inv ST. 2:
inv INJECT.
autorw'.
eelim K;
vauto.
inv AS1.
inv ST. 2:
inv INJECT.
autorw'.
eelim K;
vauto.
autorw'.
inv AS1.
inv INJECT.
simpl in LOW;
clarify.
Qed.
Definition bw_step_spec :
Prop :=
∀
s t ev t',
ev ≠
Eoutofmemory →
safe_state s →
match_state s t →
l_step t ev t' →
∃
tid, ∃
e, ∃
s',
astep ge s (
tid,
e::
nil)
s'
∧
match_ev e ev
∧
match_state s'
t'
.
Lemma bw_step :
bw_step_spec.
Proof.
intros s t ev t'
NOTOOM (
SAFE &
PROGRESS &
WFL &
WRFR)
MS'
STEP.
inv STEP.
inv tidSTEP.
inv STEP;
try (
simpl in TE;
inv TE;
clarify;
fail).
inv TE.
inv MS';
inv tsoSTEP;
unfold RtlInjectSem in *;
simpl in *.
exists tid.
exists (
TEtso (
INJECT.TSOmem (
MEalloc sp f.(
fn_stacksize)
MObjStack))).
eexists.
split.
eapply astep_free;
eauto;
try congruence.
eapply intra_step_mem.
vauto.
econstructor;
eauto.
split.
easy.
split.
vauto.
unfold tupdate.
intros t'.
destruct peq as [-> |
NE].
rewrite upd_s.
unfold push_item.
simpl.
apply lfl_snoc.
vauto.
rewrite upd_o;
intuition;
apply BUF.
inv TE.
inv MS';
inv tsoSTEP;
unfold RtlInjectSem in *;
simpl in *.
exists tid.
exists (
TEtso (
INJECT.TSOmem (
MEfree sp MObjStack))).
eexists.
split.
eapply astep_free;
eauto;
try congruence.
eapply intra_step_mem.
vauto.
econstructor;
eauto.
split.
easy.
split.
vauto.
unfold tupdate.
intros t'.
destruct peq as [-> |
NE].
rewrite upd_s.
unfold push_item.
simpl.
apply lfl_snoc.
vauto.
rewrite upd_o;
intuition;
apply BUF.
inv INJECT;
try (
elim EV;
clarify);
simpl in *;
try clarify.
inv MS'.
inv tsoSTEP.
destruct (
flush_ab BUF MEM SAFE AB)
as (
M &
FLUSH &
MM).
exists tid.
exists (
TEtso (
INJECT.TSOmem (
MEread ap (
addr_in_buf a (
buf tid))
a v))).
destruct m as (
m &
d).
destruct M as (
M &
D).
inv MM.
inv MEM.
pose proof (
flush_preserves_perm FLUSH)
as X;
simpl in X.
pose proof (
WFL tid)
as WFL'.
simpl in *.
autorw'.
pose proof (
WFL'
_ _ _ (
eq_refl _)
FLUSH LD)
as WFV.
clear WFL WFL'.
eexists.
split.
eapply astep_free;
eauto;
try congruence.
eapply intra_step_mem.
vauto.
generalize (
progress_progress'
_ PROGRESS tid).
simpl.
autorw'.
intros H.
generalize (
H _ (
eq_refl _)).
clear H.
intros (
H &
K).
generalize (
K _ _ FLUSH).
clear K.
simpl in *.
intros (
K & (
v' &
L &
L') &
FR).
eapply TSOMemoryMachine.tso_step_load;
vauto.
pose proof (
read_as_if_flush tid ap false (
buf tid)
_ _ a v FLUSH)
as Y.
case_eq (
addr_in_buf a (
buf tid));
intros;
autorw'.
assert (
Some v' =
Some v).
apply Y.
destruct ap;
vauto.
clarify.
assert (
v' =
v).
exploit Y.
destruct ap;
econstructor;
auto.
inversion 1;
inv L';
autorw'.
clarify.
split.
easy.
vauto.
inv MS'.
inv tsoSTEP.
clear EV.
exists tid.
exists (
TEtso (
INJECT.TSOmem (
MEwrite released ap a (
rs0 src)))).
generalize (
progress_progress'
_ PROGRESS tid).
simpl.
autorw'.
destruct released.
destruct m as (
m &
perm).
intros (
PS' &
perm' &
Hperm').
destruct (
PS'
_ (
eq_refl _))
as (
PS &
WFP).
eexists (
TSOMEM (
MemoryMachine.MEM m perm') (
upd buf tid (
WBufItem a (
rs0 src) ::
buf tid)),
_).
split.
eapply astep_free;
eauto.
eapply intra_step_mem.
vauto.
eapply TSOMemoryMachine.tso_step_write;
vauto.
easy.
easy.
easy.
split.
easy.
econstructor;
eauto.
intros t.
unfold tupdate.
destruct peq as [->|
NE].
rewrite upd_s.
simpl.
apply lfl_snoc.
split.
auto.
vauto.
rewrite upd_o;
auto.
intros (
PS' &
_).
destruct (
PS'
_ (
eq_refl _))
as (
PS &
WFP).
eexists (
TSOMEM m (
upd buf tid (
WBufItem a (
rs0 src) ::
buf tid)),
_).
split.
eapply astep_free;
eauto.
eapply intra_step_mem.
vauto.
eapply TSOMemoryMachine.tso_step_write;
vauto.
easy.
easy.
easy.
split.
easy.
econstructor;
eauto.
intros t.
unfold tupdate.
destruct peq as [->|
NE].
rewrite upd_s.
simpl.
apply lfl_snoc.
split.
auto.
vauto.
rewrite upd_o;
auto.
inv ASME.
inv MS'.
inv tsoSTEP;
clarify.
simpl in *.
assert (
buf tid =
nil).
generalize (
BUF tid).
rewrite Bemp.
inversion 1.
destruct (
buf tid).
easy.
simpl in *.
app_inv.
generalize (
progress_progress'
_ PROGRESS tid).
simpl.
autorw'.
intros (
instr &
q &
w &
AS &
WF &
WFP &
LD' &
WFV &
M &
ST' &
d' &
K &
K').
inv MEM.
inversion AS;
subst.
rewrite <-
H2 in H0.
clarify.
autorw'.
destruct m.
exists tid.
eexists (
TEtso (
INJECT.TSOmem _)).
eexists.
split.
eapply astep_free;
eauto.
eapply intra_step_mem;
eauto.
vauto.
simpl in *.
eapply TSOMemoryMachine.tso_step_rmw;
vauto.
easy.
easy.
easy.
split.
easy.
vauto.
inv MS'.
inv tsoSTEP.
simpl in *.
assert (
buf tid =
nil).
generalize (
BUF tid).
rewrite Bemp.
inversion 1.
destruct (
buf tid).
easy.
simpl in *.
app_inv.
exists tid.
exists (
TEtso TSOfence).
eexists.
split.
eapply astep_free;
eauto.
eapply intra_step_mem;
eauto.
vauto.
vauto.
easy.
easy.
easy.
split.
easy.
vauto.
inv MS'.
inv tsoSTEP.
simpl in *.
assert (
buf tid =
nil).
generalize (
BUF tid).
rewrite Bemp.
inversion 1.
destruct (
buf tid).
easy.
simpl in *.
app_inv.
exists tid.
exists (
TEtso TSOfence).
eexists.
split.
eapply astep_free;
eauto.
eapply intra_step_mem;
eauto.
vauto.
vauto.
easy.
easy.
easy.
split.
easy.
vauto.
inv tidSTEP;
inv MS'.
inv STEP;
try inv INJECT;
try inv ASME;
simpl in TE;
clarify;
try (
eelim EV;
clarify);
(
exists tid;
eexists;
eexists;
(
try now split;[
econstructor;
eauto;
try (
econstructor;
eauto);
vauto;
easy|
split;
vauto])
).
inv tsoSTEP;
inv MS'.
generalize (
SAFE t).
simpl in *.
generalize (
BUF t).
rewrite EQbufs.
intros K;
inv K.
assert (
I :=
rev_last_eq (
eq_sym _ _ _ H0)).
rewrite I.
intros K.
destruct (
match_bi_abi HEAD MEM K AB)
as (
n &
A &
B &
C).
inv A.
app_inv.
exists t.
eexists (
TEtso (
TSOunbuf _)).
eexists (
TSOMEM n _,
st).
split.
vauto.
split.
vauto.
econstructor;
eauto.
intros t'.
unfold tupdate.
destruct peq as [->|
NE].
rewrite upd_s.
rewrite rev_involutive.
auto.
rewrite upd_o;
auto.
inv MS'.
inv tidSTEP.
inv STEP;
try inv INJECT;
try (
simpl in TE;
solve by inversion);
try now (
exists tid;
exists TEtau;
eexists;
split; [
eapply astep_free;
eauto;
try easy;
eapply intra_step_not_mem;
eauto;
vauto |
vauto]).
now (
exists tid;
exists (
TEbegin BeginLow);
eexists;
split; [
eapply astep_free;
eauto;
try easy;
vauto |
vauto]).
destruct m.
unfold RtlInjectSem in *.
generalize (
progress_progress'
_ PROGRESS tid).
simpl in *.
rewrite Gtid.
intros Q;
destruct (
Q _ H)
as (
p' &
Hp').
exists tid;
eexists (
TEtso (
INJECT.TSOmem _));
eexists;
split; [
eapply astep_free;
eauto;
try easy;
eapply intra_step_mem;
eauto;
vauto |
vauto].
inv ASME;
clarify.
(
exists tid;
eexists (
TEend (
ReturnEvent _));
eexists;
split; [
eapply astep_free;
eauto;
try easy;
vauto |
vauto]).
econstructor;
eauto.
vauto.
easy.
exists tid.
exists (
TEtso (
INJECT.TSOmem (
MEperm PErelease))).
destruct m.
eexists (
TSOMEM _ _,
_).
split.
eapply astep_free;
eauto.
eapply intra_step_mem.
vauto.
eapply tso_step_perm.
econstructor.
econstructor.
apply release_func.
reflexivity.
easy.
easy.
easy.
intuition.
vauto.
vauto.
exists tid.
exists (
TEtso (
INJECT.TSOmem (
MEperm PEfreeperm))).
generalize (
progress_progress'
_ PROGRESS tid).
simpl in *.
autorw'.
intros (
perm' &
Hperm).
destruct m.
eexists (
TSOMEM (
MemoryMachine.MEM _ _)
_,
_).
split.
eapply astep_free;
eauto.
eapply intra_step_mem.
vauto.
eapply tso_step_perm.
vauto.
easy.
easy.
easy.
intuition.
vauto.
(
exists tid;
eexists (
TEend (
ReturnEvent _));
eexists;
split; [
eapply astep_free;
eauto;
try easy;
vauto |
vauto]).
econstructor;
eauto.
vauto.
easy.
inv tidSTEP;
inv MS'.
inv STEP;
try inv INJECT;
try inv ASME;
simpl in TE;
clarify;
try (
eelim EV;
clarify).
inv tsoSTEP.
inv MEM.
exists tid.
eexists.
eexists.
split.
eapply astep_spawn;
eauto;
vauto.
split.
easy.
econstructor;
eauto.
vauto.
intros t'.
unfold tupdate.
destruct peq as [->|
NE].
rewrite upd_s.
vauto.
rewrite upd_o.
vauto.
congruence.
inv tidSTEP;
inv MS'.
inv STEP;
try inv INJECT;
try inv ASME;
simpl in TE;
clarify;
try (
eelim EV;
clarify).
exists tid.
eexists.
eexists.
split.
eapply astep_spawn_fail;
eauto;
vauto.
vauto.
inv tidSTEP;
inv MS'.
inv STEP;
try inv INJECT;
try inv ASME;
simpl in TE;
clarify;
try (
eelim EV;
clarify).
inv tsoSTEP.
inv MEM.
exists tid.
eexists.
eexists.
split.
eapply astep_exit;
eauto;
vauto.
vauto.
apply False_ind.
inv tidSTEP.
inv tsoSTEP.
inv STEP;
clarify.
inv INJECT;
try inv ASME;
try now clarify.
simpl in TE.
inv TE.
clear EV.
inv MS'.
simpl in *.
inv MEM.
assert (
buf tid =
nil)
as B.
generalize (
BUF tid).
autorw'.
inversion 1.
destruct (
buf tid);
trivial;
simpl in *.
app_inv.
assert (
flush tid (
buf tid)
m m)
as FLUSH.
autorw'.
vauto.
generalize (
progress_progress'
_ PROGRESS tid).
simpl.
autorw'.
intros H.
generalize (
H _ (
eq_refl _)).
clear H.
intros (? &
K).
destruct m.
generalize (
K _ _ FLUSH).
clear K.
intros (? & (
v &
L &
M) &
N).
simpl in *.
inv M;
autorw'.
apply False_ind.
inv tidSTEP.
inv STEP;
try inv INJECT;
try inv ASME;
clarify.
inv TE.
clear EV.
inv MS'.
inv tsoSTEP.
simpl in *.
assert (
buf tid =
nil).
generalize (
BUF tid).
rewrite Bemp.
inversion 1.
destruct (
buf tid).
easy.
simpl in *.
app_inv.
generalize (
WRFR tid).
simpl.
autorw'.
intros K.
inv MEM.
exact (
K _ (
eq_refl _) (
eq_refl _)
LD).
apply False_ind.
inv tidSTEP.
inv STEP;
try inv INJECT;
try inv ASME;
clarify.
inv TE.
inv MS'.
inv tsoSTEP.
simpl in *.
assert (
buf tid =
nil).
generalize (
BUF tid).
rewrite Bemp.
inversion 1.
destruct (
buf tid).
easy.
simpl in *.
app_inv.
generalize (
WRFR tid).
simpl.
autorw'.
intros K.
inv MEM.
destruct (
K _ (
eq_refl _) (
eq_refl _))
as (? & ? &
K').
autorw'.
destruct FAIL as (
tid' &
p &
ch &
v &
b &
HB &
HS).
generalize (
BUF tid').
rewrite HB.
inversion 1.
subst.
inv HEAD.
symmetry in H3.
apply rev_last_eq in H3.
now elim (
K'
tid'
p v (
rev xl)).
apply False_ind.
inv tidSTEP.
inv STEP;
try inv INJECT;
try inv ASME;
clarify.
inv TE.
clear EV.
inv tsoSTEP.
inv MS'.
simpl in *.
inv MEM.
assert (
flush tid (
buf tid)
m m)
as FLUSH.
replace (
buf tid)
with (@
nil buf_item).
vauto.
generalize (
BUF tid).
autorw'.
inversion 1.
destruct (
buf tid);
trivial;
simpl in *.
app_inv.
generalize (
progress_progress'
_ PROGRESS tid).
simpl.
autorw'.
intros (
instr &
q &
w &
AS &
WF &
WFP &
LD' &
WFV &
M &
ST' &
d' &
K &
K').
inv AS.
rewrite <-
H in H1.
clarify.
autorw'.
apply False_ind.
eapply safe_not_stuck;
eauto.
split;
intuition.
elim NOTOOM;
reflexivity.
inv tidSTEP.
inv STEP;
try inv INJECT;
try inv ASME;
clarify.
inv tidSTEP.
inv STEP;
try inv INJECT;
try inv ASME;
clarify.
inv tidSTEP.
inv STEP;
try inv INJECT;
try inv ASME;
clarify.
inv tidSTEP.
inv STEP;
try inv INJECT;
try inv ASME;
clarify.
inv tidSTEP.
inv STEP;
try inv INJECT;
try inv ASME;
clarify.
inv tidSTEP.
inv STEP;
try inv INJECT;
try inv ASME;
clarify.
Qed.
Lemma bw_taustar :
∀
j j',
taustar (
rtli_lts ge)
j j' →
∀
i,
match_state i j →
(∀
s,
reachable i s →
can_unbuffer (
fst s) ∧
progress s ∧
wf_load s) →
∃
tr, ∃
i',
low_trace ge i tr i' ∧
filter_fullevent tr =
nil ∧
match_state i'
j'.
Proof.
unfold rtli_lts.
simpl.
induction 1.
intros i H _.
exists nil.
exists i.
simpl.
intuition.
split.
vauto.
intuition.
simpl in *.
intros i MS SAFE.
assert (
Etau ≠
Eoutofmemory)
as zz by discriminate.
assert (
safe_state i)
as yy.
destruct (
SAFE i (
reachable_refl _)).
split.
intros tid.
destruct i;
simpl.
eapply (
can_unbuffer_safe).
eapply SAFE.
eapply reachable_refl.
intuition.
apply (
can_unbuffer_can_write_and_free i).
eapply SAFE.
apply reachable_refl.
assumption.
destruct (
bw_step _ _ _ _ zz yy MS H)
as (
tid &
e &
i' &
STEP &
ME &
MS').
assert (∀
s,
reachable i'
s →
can_unbuffer (
fst s) ∧
progress s ∧
wf_load s)
as SAFE'.
intros u v.
apply SAFE.
apply reachable_trans with i';
trivial.
eexists.
vauto.
destruct (
IHtaustar _ MS'
SAFE')
as (
tr &
i'' & (
TR &
LOW) &
TAU &
MS'').
exists (
tr ++ (
tid,
e::
nil)::
nil).
exists i''.
split.
split.
apply trace_app with i'.
vauto.
trivial.
intros t'.
rewrite in_app_iff.
intros [
K|
K].
exact (
LOW t'
K).
inv K;
clarify.
split.
rewrite filter_fullevent_app,
TAU.
simpl.
destruct e;
clarify.
assumption.
Qed.
Lemma bw_fintrace :
∀
j trace j',
Traces.fintrace (
rtli_lts ge)
j trace j' →
∀
i,
match_state i j →
(∀
s,
reachable i s →
can_unbuffer (
fst s) ∧
progress s ∧
wf_load s) →
∃
tr, ∃
i',
low_trace ge i tr i' ∧
filter_fullevent tr =
rev trace ∧
match_state i'
j'.
Proof.
unfold rtli_lts.
simpl.
induction 1.
clarify.
now eauto using bw_taustar.
simpl in *.
clarify.
intros i MS SAFE.
destruct TS as (
si &
TAU &
STEP).
simpl in *.
destruct (
bw_taustar _ _ TAU _ MS SAFE)
as (
ti &
ii & (
X &
LOWi) &
TAUi &
MSi).
assert (
Evisible ev ≠
Eoutofmemory)
as zz by discriminate.
assert (
reachable i ii)
as tt.
now exists ti.
assert (
safe_state ii)
as yy.
split.
intros tid.
destruct ii;
simpl.
eapply can_unbuffer_safe.
eapply SAFE.
eassumption.
repeat split;
try now eapply SAFE.
eapply can_unbuffer_can_write_and_free. 2:
eassumption.
eapply SAFE.
now eapply SAFE.
destruct (
bw_step _ _ _ _ zz yy MSi STEP)
as (
tid &
e &
i'' &
STEP'' &
ME &
MS'').
assert (
reachable i i'').
eapply reachable_trans with ii.
trivial.
exists ((
tid,
e::
nil)::
nil).
vauto.
destruct (
IHfintrace _ MS'')
as (
L' &
i' & (
X' &
LOWi') &
ME' &
MS').
intros q Q.
apply SAFE.
eapply reachable_trans with i'';
trivial.
exists (
L' ++ ((
tid,
e::
nil) ::
nil) ++
ti).
exists i'.
intuition.
split.
eapply trace_app;
eauto.
eapply trace_app;
eauto.
vauto.
intros t'.
rewrite in_app_iff.
rewrite in_app_iff.
simpl.
intros [
K|[[
K|
K]|
K]];
clarify.
exact (
LOWi'
t'
K).
exact (
LOWi t'
K).
repeat rewrite filter_fullevent_app.
rewrite ME',
TAUi.
destruct e;
try destruct be;
try destruct e;
clarify. 2:
congruence.
simpl.
inv ME.
reflexivity.
inv ME.
elim EV.
reflexivity.
Qed.
End LOWSIM.
Definition init (
p:
program) (
ge:
genv) (
s:
state) :
Prop :=
(∀
p, (
fst s).(
MemoryMachine.perms)
p =
empty_perm)
∧ (∀
tid, (
fst s).(
TSOMemoryMachine.buffers)
tid =
nil)
∧ (
TSO.init RtlInjectSem p nil ge (
mktsostate (
fun _ =>
nil) (
fst s).(
MemoryMachine.mem_rtl),
snd s)).
Definition safe_program (
p:
program) :
Prop :=
∀
ge s,
init p ge s →
∀
s',
reachable ge s s' →
can_unbuffer (
fst s') ∧
progress ge s' ∧
wf_load ge s'.
Inductive low_traces (
p:
program) :
Traces.trace event →
Prop :=
|
LTr ge i f tr trf t
(
INIT:
init p ge i)
(
TRACE:
low_trace ge i tr f)
(
FILTER:
trf =
rev (
filter_fullevent tr))
(
NOFAIL: ¬
In Efail trf)
(
TEQ:
Traces.appt trf Traces.Send =
t)
:
low_traces p t
|
LTrF ge i f f'
tr trf t t'
x fe
(
INIT:
init p ge i)
(
TRACE:
low_trace ge i tr f)
(
FILTER:
trf =
rev (
filter_fullevent tr))
(
NOFAIL: ¬
In Efail trf)
(
FAILSTEP:
astep ge f (
x, (
fe::
nil))
f')
(
FAIL:
fe =
TEext Efail ∨
fe =
TEend FailEvent ∨
fe =
TEend ReturnVoid)
(
TEQ:
Traces.appt trf t' =
t)
:
low_traces p t
.
Lemma init_ex p ge s :
TSO.init RtlInjectSem p nil ge s →
∃
s',
init p ge s' ∧
match_state s'
s.
Proof.
destruct s as (
m &
st).
intros (
mainst &
maintid &
im &
mptr &
GE &
FS &
I &
LTS).
exists (
TSOMEM (
MemoryMachine.MEM im (
fun _ =>
empty_perm)) (
fun _ =>
nil),
st).
split.
split.
easy.
split.
easy.
simpl.
exists mainst.
exists maintid.
exists im.
exists mptr.
intuition.
f_equal.
simpl.
clarify.
vauto.
Qed.
Inductive tfin :
Traces.trace event ->
Prop :=
|
tfin_end:
tfin Traces.Send
|
tfin_cons x t:
tfin t →
tfin (
Traces.Scons x t)
.
Lemma fintrace_no_fail {
ge j trace j'} :
Traces.fintrace (
rtli_lts ge)
j trace j' →
¬
In Efail trace.
Proof.
induction 1; subst. intuition.
intros [K|K]; intuition.
Qed.
Lemma bw_sim p :
safe_program p →
∀
trace,
rtli_traces p nil trace →
tfin trace →
low_traces p trace.
Proof.
intros SAFE trace (
ge &
j &
J &
TR)
FIN.
inv TR.
destruct (
init_ex _ _ _ J)
as (
i &
I &
MS).
pose proof (
SAFE _ _ I)
as S.
destruct (
bw_fintrace ge _ _ _ PREF i MS S)
as (
tr &
i' &
TR &
EV &
_).
econstructor;
eauto.
rewrite EV.
rewrite rev_involutive.
eapply fintrace_no_fail;
eassumption.
now autorw';
rewrite rev_involutive.
destruct (
init_ex _ _ _ J)
as (
i &
I &
MS).
pose proof (
SAFE _ _ I)
as S.
destruct (
bw_fintrace ge _ _ _ PREF i MS S)
as (
tr &
i' &
TR &
EV &
MSi).
assert (
Evisible Efail ≠
Eoutofmemory)
as zz by discriminate.
inv TR.
assert (
reachable ge i i')
as tt.
now exists tr.
assert (
safe_state ge i')
as yy.
split.
intros tid.
destruct i';
simpl.
eapply can_unbuffer_safe.
eapply S.
eassumption.
repeat split;
try now eapply S.
eapply can_unbuffer_can_write_and_free. 2:
eassumption.
eapply S.
now eapply S.
destruct (
bw_step ge _ _ _ _ zz yy MSi FAIL)
as (
tid &
e &
i'' &
STEP'' &
ME &
MS'').
assert (
reachable ge i i'').
eapply reachable_trans with i'.
trivial.
exists ((
tid,
e::
nil)::
nil).
vauto.
eapply LTrF;
eauto.
split.
eapply trace_app.
eassumption.
vauto.
intuition.
simpl.
rewrite EV.
rewrite rev_involutive.
eapply fintrace_no_fail;
eassumption.
destruct e;
try destruct be;
try destruct e;
try destruct ev;
clarify;
intuition.
now simpl;
autorw';
rewrite rev_involutive.
apply False_ind.
clear -
FIN.
induction l;
inv FIN.
intuition.
apply False_ind.
clear -
FIN.
induction l;
inv FIN.
intuition.
apply False_ind.
clear J.
generalize dependent j.
induction FIN;
inversion 1.
subst.
eauto.
Qed.