From ShiftReset Require Import Basics ShiftFree.
Lemmas about satisfies
Lemma ens_void_pure_intro :
forall P s h,
P ->
satisfies s s h h (
norm vunit) (
ens_ \[
P]).
Proof.
intros.
unfold ens_.
constructor.
exists vunit.
exists empty_heap.
splits*.
{ rewrite hstar_hpure_r.
intuition.
apply hpure_intro.
reflexivity. }
Qed.
Lemma ens_pure_intro :
forall P s h r,
P r ->
satisfies s s h h (
norm r) (
ens (
fun v => \[
P v])).
Proof.
intros.
constructor.
exists r.
exists empty_heap.
hint hpure_intro.
splits*.
Qed.
Lemma ens_void_pure_inv :
forall P s1 s2 h1 h2 R,
satisfies s1 s2 h1 h2 R (
ens_ \[
P]) ->
P /\
h1 =
h2 /\
s1 =
s2 /\
R =
norm vunit.
Proof.
intros.
inverts H as H. destr H.
rewrite hstar_hpure_l in H. destr H.
apply hpure_inv in H4. destr H4. subst.
intuition.
Qed.
Lemma empty_intro :
forall s1 h1,
satisfies s1 s1 h1 h1 (
norm vunit)
empty.
Proof.
intros.
unfold empty, ens_.
constructor.
exists vunit.
exists empty_heap.
splits*.
{ rewrite hstar_hpure_l.
intuition.
apply hpure_intro.
constructor. }
Qed.
Lemma empty_inv :
forall s1 s2 h1 h2 R,
satisfies s1 s2 h1 h2 R empty ->
s1 =
s2 /\
h1 =
h2 /\
R =
norm vunit.
Proof.
unfold empty.
intros.
apply ens_void_pure_inv in H.
intuition.
Qed.
Lemma ens_store_frame :
forall s1 s2 h1 h2 R x uf Q,
satisfies s1 s2 h1 h2 R (
ens Q) ->
satisfies (
Fmap.update s1 x uf) (
Fmap.update s2 x uf)
h1 h2 R (
ens Q).
Proof.
intros.
inverts H as H. destr H.
subst.
apply s_ens. exs.
intuition eauto.
Qed.
Examples for semantics
Module Examples.
Example e1_undelimited :
forall k,
exists R,
satisfies empty_env empty_env empty_heap empty_heap R
(
sh k (
ens (
fun r2 => \[
r2 =
vint 1]))).
Proof.
intros.
eexists.
apply* s_sh.
Qed.
Example e2_reset_value :
satisfies empty_env empty_env empty_heap empty_heap (
norm (
vint 1))
(
rs (
ens (
fun r => \[
r =
vint 1]))).
Proof.
intros.
apply s_rs_val.
apply ens_pure_intro.
reflexivity.
Qed.
Example e3_rs_sh_no_k :
forall k,
exists s,
satisfies empty_env s empty_heap empty_heap (
norm (
vint 1))
(
rs (
sh k (
ens (
fun r => \[
r =
vint 1])))).
Proof.
intros.
eexists.
applys s_rs_sh k.
{ apply* s_sh. }
{ apply s_rs_val.
apply ens_pure_intro.
reflexivity. }
Qed.
Definition vplus (
a b:
val) :
val :=
match a,
b with
|
vint a,
vint b =>
vint (
a +
b)
| _, _ =>
vunit
end.
reset (1 + shift k (k 2)).
Example e4_rs_sh_k :
forall k,
exists s,
satisfies empty_env s empty_heap empty_heap (
norm (
vint 3))
(
rs (
sh k (
unk k (
vint 2));;
ens (
fun r => \[
r =
vint (1 + 2)]))).
Proof.
intros.
eexists.
applys s_rs_sh k.
{
apply s_bind_sh.
apply* s_sh. }
{ apply s_rs_val.
eapply s_unk. resolve_fn_in_env.
simpl.
apply s_rs_val.
eapply s_bind.
{ apply ens_pure_intro. jauto. }
{ apply ens_pure_intro. jauto. }
}
Qed.
(reset (shift k (fun a -> k a))) 4 ==> 4
- The whole thing returns what the application of f/k returns
- The result of the shift is 4 due to the identity k
- The result of the reset is a function; 4 is the result of an inner reset that appears in the course of reduction
Example e5_shift_k :
forall k xf,
k <>
xf ->
exists s,
satisfies empty_env s empty_heap empty_heap (
norm (
vint 4))
(
rs (
sh k (
defun xf (
unk k);;
ens (
fun r => \[
r =
vfptr xf])));;
unk xf (
vint 4)).
Proof.
intros.
eexists.
eapply s_bind.
{
applys s_rs_sh k.
apply* s_sh.
{ apply s_rs_val.
eapply s_bind.
apply* s_defun.
apply ens_pure_intro. reflexivity. }
}
{
eapply s_unk. resolve_fn_in_env.
simpl.
eapply s_unk.
{ unfold Fmap.update.
rewrite Fmap.read_union_r.
rewrite Fmap.read_union_l.
apply Fmap.read_single.
apply Fmap.indom_single.
apply fmap_not_indom_of_neq.
easy. }
simpl.
apply s_rs_val.
apply~ ens_pure_intro.
}
Qed.
(reset 1 + (shift k (fun a -> k a))) 4 ==> 5
- res of shift = arg of k = 4
- res of reset = res of shift body = fptr
- final res is that of the inner reset, which doesn't occur syntacically in the code as it is produced by the "handling" of the shift.
Example e6_shift_k :
forall k xf,
k <>
xf ->
exists s,
satisfies empty_env s empty_heap empty_heap (
norm (
vint 5))
(
rs (
bind (
sh k (
defun xf (
unk k);;
ens (
fun r => \[
r =
vfptr xf])))
(
fun sr =>
ens (
fun r => \[
r =
vplus (
vint 1)
sr])));;
unk xf (
vint 4)).
Proof.
intros.
eexists.
eapply s_bind.
{
applys s_rs_sh k.
{ apply s_bind_sh.
apply* s_sh. }
{ apply s_rs_val.
eapply s_seq.
apply* s_defun.
apply* ens_pure_intro. }
}
{
eapply s_unk. resolve_fn_in_env. simpl.
eapply s_unk.
{ unfold Fmap.update.
rewrite Fmap.read_union_r.
rewrite Fmap.read_union_l.
apply Fmap.read_single.
apply Fmap.indom_single.
apply* fmap_not_indom_of_neq. }
simpl.
apply s_rs_val.
eapply s_bind. apply* ens_pure_intro.
simpl.
apply* ens_pure_intro.
}
Qed.
End Examples.
Lemma ens_req_inv :
forall s1 s2 h1 h2 R H f,
satisfies s1 s2 h1 h2 R (
ens_ H;;
req H f) ->
satisfies s1 s2 h1 h2 R f.
Proof.
intros.
inverts H0 as H0; no_shift.
inverts H0 as H0. destr H0. hinv H0. hinv H0.
inverts H8 as H15. specializes H15 H3.
subst. rew_fmap *.
Qed.
Lemma req_empty_inv :
forall s1 s2 h1 h2 R f,
satisfies s1 s2 h1 h2 R (
req \[]
f) ->
satisfies s1 s2 h1 h2 R f.
Proof.
intros.
inverts H as H6. specializes H6 empty_heap h1 ___.
apply hempty_intro.
Qed.
Lemma req_empty_intro :
forall s1 s2 h1 h2 R f,
satisfies s1 s2 h1 h2 R f ->
satisfies s1 s2 h1 h2 R (
req \[]
f).
Proof.
intros.
apply s_req. intros.
hinv H0.
subst. rew_fmap *.
Qed.
Lemma ens_empty_intro :
forall s1 h1 r,
satisfies s1 s1 h1 h1 (
norm r) (
ens (
fun r => \[])).
Proof.
intros.
apply s_ens.
exists r empty_heap.
intuition fmap_eq.
constructor.
Qed.
Lemma ens_void_empty_intro :
forall s1 h1,
satisfies s1 s1 h1 h1 (
norm vunit) (
ens_ \[]).
Proof.
intros.
constructor.
exs.
splits*.
hintro.
splits*.
hintro.
rew_fmap.
reflexivity.
Qed.
Lemma satisfies_ens_void :
forall H1 H2 s1 s2 h1 h2 R,
H1 ==>
H2 ->
satisfies s1 s2 h1 h2 R (
ens_ H1) ->
satisfies s1 s2 h1 h2 R (
ens_ H2).
Proof.
intros.
inverts H0 as H3. destruct H3 as (v&h3&?&?&?&?).
constructor. exists v. exists h3.
intuition.
rewrite hstar_hpure_l in H3.
rewrite hstar_hpure_l.
intuition.
Qed.
Lemma ens_inv :
forall s1 s2 h1 h2 R Q,
satisfies s1 s2 h1 h2 R (
ens Q) ->
s1 =
s2.
Proof.
intros.
inverts H as H. destr H.
reflexivity.
Qed.
Lemma unk_inv :
forall s1 s2 h1 h2 R x a uf,
Fmap.read s1 x =
uf ->
satisfies s1 s2 h1 h2 R (
unk x a) ->
satisfies s1 s2 h1 h2 R (
uf a).
Proof.
intros.
inverts H0 as H0.
rewrite H in H0.
assumption.
Qed.
Lemma satisfies_ens_ens_void_split :
forall H1 H2 s1 s2 h1 h2 R,
satisfies s1 s2 h1 h2 R (
ens_ (
H1 \*
H2)) ->
satisfies s1 s2 h1 h2 R (
ens_ H1;;
ens_ H2).
Proof.
intros.
inverts H as H. destruct H as (v&h3&H3&H4&H5&H6).
rewrite hstar_hpure_l in H4. destruct H4 as (H4&H7).
apply hstar_inv in H7. destruct H7 as (h0&h4&H8&H9&H10&H11).
applys s_seq.
{ constructor. exists vunit. exists h0. intuition. rewrite hstar_hpure_l. intuition. }
{ constructor. exists v. exists h4. intuition. rewrite hstar_hpure_l. intuition. }
Qed.
Lemma satisfies_ens_ens_void_combine :
forall H1 H2 s1 s2 h1 h2 R,
satisfies s1 s2 h1 h2 R (
ens_ H1;;
ens_ H2) ->
satisfies s1 s2 h1 h2 R (
ens_ (
H1 \*
H2)).
Proof.
intros.
inverts H as H; no_shift. destr H.
inverts H as H. destr H.
inverts H9 as H9. destr H9.
hinv H. hinv H. hinv H6. hinv H6.
applys_eq s_ens_. injects H0. subst. reflexivity.
exists (h0 \u h4).
splits*.
subst.
hintro; jauto.
rew_fmap *.
rew_fmap *.
Qed.
Lemma fall_intro :
forall s1 s2 h1 h2 R A (
fctx:
A ->
flow),
(
forall b,
satisfies s1 s2 h1 h2 R (
fctx b)) ->
satisfies s1 s2 h1 h2 R (
∀ b,
fctx b).
Proof.
intros.
constructor.
auto.
Qed.
Lemma req_pure_inv:
forall s1 s2 h1 h2 R P f,
P ->
satisfies s1 s2 h1 h2 R (
req \[
P]
f) ->
satisfies s1 s2 h1 h2 R f.
Proof.
intros.
inverts H0 as H7.
specializes H7 empty_heap h1. apply H7.
hintro. assumption. fmap_eq. fmap_disjoint.
Qed.
Lemma req_pure_intro :
forall s1 s2 h1 h2 R P f,
(
P ->
satisfies s1 s2 h1 h2 R f) ->
satisfies s1 s2 h1 h2 R (
req \[
P]
f).
Proof.
intros.
apply s_req. intros.
hinv H0. subst. rew_fmap.
apply* H.
Qed.