Timings for twophase_refinement_proof.v
- /home/gitlab-runner/builds/gGKko-aj/0/coq/coq/_bench/opam.OLD/ocaml-OLD/.opam-switch/build/coq-perennial.dev/./src/program_proof/txn/twophase_refinement_proof.v.timing
- /home/gitlab-runner/builds/gGKko-aj/0/coq/coq/_bench/opam.NEW/ocaml-NEW/.opam-switch/build/coq-perennial.dev/./src/program_proof/txn/twophase_refinement_proof.v.timing
From Perennial.goose_lang.lib Require Import encoding crash_lock.
From Perennial.program_proof Require Import disk_prelude.
From Perennial.program_proof Require Import disk_lib.
From Perennial.program_proof Require Import
txn.typed_translate txn.wrapper_proof txn.wrapper_init_proof
txn.twophase_refinement_defs txn.twophase_sub_logical_reln_defs
txn.typed_translate_facts
alloc.alloc_proof.
From Perennial.goose_lang Require Import crash_modality.
From Perennial.goose_lang.ffi Require Import jrnl_ffi.
From Perennial.goose_lang Require Import logical_reln_defns logical_reln_adeq spec_assert metatheory.
From Perennial.base_logic Require Import ghost_var.
From Perennial.program_proof Require Import lockmap_proof.
From Goose Require github_com.mit_pdos.go_journal.obj.
#[global]
Existing Instances jrnl_spec_ext jrnl_spec_ffi_model jrnl_spec_ext_semantics jrnl_spec_ffi_interp jrnl_spec_interp_adequacy.
Context (JRNL_KIND_SIZE : nat).
Definition dinit0 sz : gmap Z Block :=
gset_to_gmap block0 (list_to_set $ seqZ 513 (sz-513)).
Lemma dom_dinit0:
∀ sz : Z,
dom (dinit0 sz) = list_to_set (seqZ 513 (sz - 513)).
rewrite dom_gset_to_gmap.
Opaque crash_borrow.pre_borrow.
Lemma jrnl_init_obligation1: sty_init_obligation1 (twophaseTy_update_model JRNL_KIND_SIZE) (twophase_initP JRNL_KIND_SIZE).
rewrite /sty_init_obligation1//=.
iIntros (? hG hRG hJrnl σs σi Hinit) "Hdisk".
rewrite /jrnl_start /twophase_init.
destruct Hinit as (sz&kinds&Hsize2&Hnn&Hnonneg&Heqi&Heqs&Hdom&Hkind_size).
iIntros "(Hclosed_frag&Hjrnl_frag)".
iDestruct "Hjrnl_frag" as "(Hsmapstos&Hcrashtoks&Hcrash_ctx&Hkinds&Hdom&Hfull)".
rewrite /twophase_crash_cond_full.
iMod (sep_jrnl_recovery_proof.is_txn_durable_init
(dinit0 (sz + 513)) kinds sz with "[Hdisk]") as "H".
iDestruct (disk_array_init_disk with "Hdisk") as "Hdisk".
rewrite -recovery_proof.repeat_to_replicate.
rewrite repeat_app disk_array_app.
iDestruct "Hdisk" as "[Hlog Hd]".
replace (0 + (Z.of_nat 513))%Z with 513%Z by lia.
iSplitL "Hlog"; first by iExact "Hlog".
iDestruct "H" as (γ) "(%Hγ&His_txn_durable&#Hlb&Himapstos)".
iExists tt, γ, _, _, (recovery_proof.kind_heap0 kinds).
iFrame "His_txn_durable".
iDestruct "Hpre" as "($&Hpre)".
eapply map_Forall_impl; first eapply kind_heap0_ok.
rewrite Hdom elem_of_list_to_set elem_of_list_fmap; intros (x&->&Hin).
apply elem_of_seqZ in Hin.
rewrite /block_bytes in Hsize2.
iFrame "Hfull Hclosed_frag Hcrash_ctx".
iEval (rewrite big_sepM_fmap) in "Hsmapstos".
iEval (rewrite big_sepM_fmap) in "Hcrashtoks".
iDestruct (big_sepM_sep with "[$Hsmapstos $Hcrashtoks]") as "H".
iDestruct (big_sepM_sep with "[$H $Himapstos]") as "H".
iApply (big_sepM_mono with "H").
iIntros (?? Hlookup) "(Hkind&Hmod&Hdurable)".
iApply (crash_borrow.pre_borrowN_big_sepM with "[$]").
Lemma jrnl_init_obligation2: sty_init_obligation2 (twophase_initP JRNL_KIND_SIZE).
intros ???? (sz&?&Hsize2&?&?&?&?&Hdom&Hksz).
eapply wf_jrnl_alt, kind_heap0_ok.
rewrite Hdom elem_of_list_to_set elem_of_list_fmap; intros (?&->&Hin).
apply elem_of_seqZ in Hin.
rewrite /block_bytes in Hsize2.
Lemma jrnl_rules_obligation:
@sty_rules_obligation _ _ disk_semantics _ _ _ _ _ _ (twophaseTy_model JRNL_KIND_SIZE) jrnl_trans.
intros vs0 vs v0 v0' t1 t2 Htype0 Htrans.
inversion Htype0 as [op Heq|op Heq]; subst.
iIntros (????) "#Hinv #Hspec #Hval".
iDestruct "Hval" as %[-> ->].
iMod (ghost_step_lifting_puredet with "[$Hj]") as "(Hj&_)".
apply head_prim_step_trans.
iDestruct "Hspec" as "(?&?)".
wp_apply (wp_Init JRNL_KIND_SIZE (nroot.@"H") with "[Hj]").
iIntros (l') "(Hj&Hopen&H)".
rewrite /val_interp//=/twophase_val_interp.
iFrame "Htwophase Hopen".
iIntros (????) "#Hinv #Hspec #Hval".
iDestruct "Hval" as %(n&->&->).
iMod (ghost_step_lifting_puredet with "[$Hj]") as "(Hj&_)".
apply head_prim_step_trans.
iDestruct "Hspec" as "(?&?)".
iMod (ghost_step_jrnl_mkalloc with "[$] [$Hj]") as "H".
iDestruct "H" as (l [Hgt0 Hmod8]) "(Hj&Halloc)".
wp_apply (wp_MkMaxAlloc).
Lemma fmap_unit_jrnl_dom_equal (jd jd': gmap addr_proof.addr obj) :
dom jd = dom jd' →
(λ _, ()) <$> jd = (λ _, ()) <$> jd'.
destruct (decide (i ∈ dom jd)) as [Hin|Hnin].
assert (Hin': i ∈ dom jd').
apply elem_of_dom in Hin as (?&->).
apply elem_of_dom in Hin' as (?&->).
assert (Hnin': ¬ i ∈ dom jd').
apply not_elem_of_dom in Hnin as ->.
apply not_elem_of_dom in Hnin' as ->.
Opaque crash_borrow.crash_borrow.
Lemma jrnl_crash_inv_obligation:
@sty_crash_inv_obligation _ _ disk_semantics _ _ _ _ _ _ (twophaseTy_model JRNL_KIND_SIZE).
rewrite /sty_crash_inv_obligation//=.
iIntros (? hG hRG hJrnl) "H Hspec #Hspec_crash_ctx".
iDestruct "H" as (????) "(Hcrash_cond&Hauth&Htok&Hclosed_frag&Hpre&HpreM)".
iAssert (jrnl_dom (dom mt)) with "[Hcrash_cond]" as "#Hdom".
iDestruct "Hcrash_cond" as "(H1&?&?&H2)".
rewrite /twophase_init/twophase_inv.
iDestruct (crash_borrow.crash_borrow_init_cancel
(∃ γ dinit logm mt',
([∗ map] _ ↦ _ ∈ mt', crash_borrow.pre_borrow) ∗
twophase_crash_cond_full JRNL_KIND_SIZE γ dinit logm mt')%I
(∃ γ dinit logm mt',
twophase_crash_cond_full JRNL_KIND_SIZE γ dinit logm mt')%I
with "[$] [Hcrash_cond HpreM] []") as "Hinit".
(* "(Hna_crash_inv&Hcancel)". *)
iDestruct "H" as "(_&$)".
iMod (ghost_var_alloc (0, expr_id)) as (γghost) "Hghost".
rewrite /twophase_crash_tok.
iApply (init_cancel_fupd ⊤).
iApply (init_cancel_wand with "Hinit [-Htok Hauth]").
iMod (inv_alloc twophaseInitN _ (twophase_inv_inner JRNL_KIND_SIZE γghost) with
"[Hclosed_frag Hborrow Hghost]") as "#Hinv".
iFrame "Hinv Hspec_crash_ctx".
iDestruct "H" as "Hcancel".
iRename "Hdom" into "Hdom'".
iDestruct "Hdom" as "#Hdom".
iDestruct (jrnl_dom_agree with "[$Hdom] [$Hdom']") as %Hdom.
rewrite /twophase_crash_cond.
rewrite /twophase_crash_tok.
rewrite /jrnl_mapsto_own.
iEval (setoid_rewrite sep_assoc) in "Hmapstos".
iDestruct (big_sepM_sep with "Hmapstos") as "(H1&H2)".
iSplitL "H1 Htxn_durable".
iExists {| jrnlData := (bufObj_to_obj <$> _); jrnlKinds := ∅; jrnlAllocs := ∅ |}.
rewrite /source_crash_ctx.
rewrite /jrnl_full_crash_tok.
erewrite (fmap_unit_jrnl_dom_equal (bufObj_to_obj <$> mt) (bufObj_to_obj <$> mt')); last first.
Lemma jrnl_crash_obligation:
@sty_crash_obligation _ _ disk_semantics _ _ _ _ _ _ (twophaseTy_model JRNL_KIND_SIZE).
rewrite /sty_crash_obligation//=.
iIntros (? hG hRG hJrnl) "Hinv Hcrash_cond".
iDestruct "H" as (??) "(_&H)".
iDestruct "H" as %[Heq1 Heq2].
iExists
(RecordSet.set trace add_crash
(RecordSet.set world (λ w : @ffi_state jrnl_model, match w with
| Closed s => Closed (clearAllocs s)
| Opened s => Closed (clearAllocs s)
end : @ffi_state jrnl_model)
(RecordSet.set heap (λ _ : gmap loc (nonAtomic val), ∅) σs))).
destruct σs.(world) => //=.
iIntros (hRG' Heq) "Hrestart".
assert (∃ s, σs.(world) = Closed s ∨ σs.(world) = Opened s) as (s&Hcase).
destruct σs.(world); eauto.
iAssert (jrnl_restart _ (Closed s))%I with "[Hrestart]" as "Hrestart".
destruct Hcase as [Hcase|Hcase]; rewrite Hcase; eauto.
rewrite /jrnl_state_restart.
iDestruct "Hrestart" as "(Hclosed&Hcrash_toks&Hcrash_ctx&#Hkinds&#Hdom&Hfull)".
rewrite /twophase_crash_cond.
rewrite /twophase_update.
iDestruct "Hcrash_cond" as (????) "H".
iRename "Hdom" into "Hdom'".
iDestruct "Hdom" as "#Hdom".
iExists γ, dinit, logm, mt.
rewrite /twophase_crash_cond_full.
rewrite /sep_jrnl_recovery_proof.is_txn_durable.
iFrame "Hlogm Hasync_ctx".
specialize (@recovery_proof.is_txn_durable_stable) => Hcrash.
rewrite /IntoCrash in Hcrash.
iPoseProof (Hcrash _ _ hG _ with "Hlower_durable") as "H".
iMod ("H" $! _ _ (goose_localGS (heapGS:=hG')) with "[]") as "(?&$)".
iAssert (⌜ dom mt = dom (jrnlData s)⌝)%I with "[]" as %Hdomeq.
destruct Heq as (Heq_data&Heq_kinds&Heq_dom&Heq_data_name&Heq_kinds_name&Heq_dom_name).
rewrite /jrnl_mapsto/jrnl_kinds.
rewrite Heq_dom Heq_dom_name.
iDestruct (jrnl_dom_agree with "Hdom Hdom'") as %Hdom; eauto.
iDestruct (big_sepM_dom with "Hcrash_toks") as "Hcrash_toks".
iDestruct (big_sepM_dom with "Hcrash_toks") as "Hcrash_toks".
iCombine "Hmapstos Hcrash_toks" as "Hmapstos".
destruct Heq as (Heq_data&Heq_kinds&Hdom&Heq_data_name&Heq_kinds_name&_).
rewrite /jrnl_mapsto/jrnl_kinds.
rewrite Heq_kinds Heq_kinds_name.
iApply (big_sepM_mono with "Hmapstos").
iIntros (???) "(($&Hjrnl)&Htok)".
rewrite /jrnl_mapsto_own.
destruct Heq as (Heq_data&Heq_kinds&Hdom&Heq_data_name&Heq_kinds_name&_).
rewrite /jrnl_mapsto/jrnl_kinds.
rewrite Heq_data Heq_data_name Heq_kinds Heq_kinds_name.
iDestruct "Hpre" as "($&HpreM)".
eapply fmap_unit_jrnl_dom_equal; eauto => //=.
iApply (crash_borrow.pre_borrowN_big_sepM with "HpreM").
Lemma jrnl_inv_twophase_pre {Σ} {hG: heapGS Σ} {hRG: refinement_heapG Σ}
{hJrnl : twophaseG Σ} vs v:
twophase_inv JRNL_KIND_SIZE -∗
val_interp (smodel := twophaseTy_model JRNL_KIND_SIZE) (hS := hJrnl) (@extT jrnl_val_ty JrnlT) vs v -∗
∃ (l : loc) γ γ' objs_dom dinit, ⌜ v = #l ⌝ ∗ is_twophase_pre l γ γ' dinit objs_dom.
iDestruct "H2" as (l γ γ' dinit objs_dom -> ->) "(H&?)".
iExists l, γ, γ', objs_dom, dinit.
Ltac unfold_expr_vars :=
match goal with
| [ H : _ ∉ expr_vars _ |- _ ] => rewrite /expr_vars -/expr_vars in H
| [ H : _ ∉ val_vars _ |- _ ] => rewrite /val_vars -/val_vars in H
end.
Lemma atomic_body_expr_subst :
∀ Γ x e e' t v,
x ∉ dom Γ →
x ∉ expr_vars e →
atomic_body_expr_transTy Γ (Var x) e e' t →
atomic_body_expr_transTy Γ (of_val v) e (subst x v e') t.
intros ?????? Hnot_in1 Hnot_in2 Htyping.
remember (Var x) as tph' eqn:Heq.
revert Hnot_in1 Hnot_in2.
induction Htyping using @expr_typing_ind with
(P := (λ Γ tph' es e t
(HTYPE: atomic_body_expr_transTy Γ tph' es e t),
tph' = Var x →
x ∉ dom Γ →
x ∉ expr_vars es →
atomic_body_expr_transTy Γ (of_val v) es (subst x v e) t))
(P0 := (λ Γ tph' vs vi t
(HTYPE: atomic_body_val_transTy Γ tph' vs vi t),
tph' = Var x →
x ∉ dom Γ →
x ∉ val_vars vs →
atomic_body_val_transTy Γ (of_val v) vs vi t));
try (intros; subst; simpl; econstructor; eauto; done);
try (intros; subst; simpl;
econstructor; eauto;
[ eapply IHHtyping1; eauto; unfold_expr_vars; set_solver |
eapply IHHtyping2; eauto; unfold_expr_vars; set_solver ]; done);
try (intros; subst; simpl;
econstructor; eauto;
[ eapply IHHtyping1; eauto; unfold_expr_vars; set_solver |
eapply IHHtyping2; eauto; unfold_expr_vars; set_solver |
eapply IHHtyping3; eauto; unfold_expr_vars; set_solver ]; done).
subst; try econstructor; eauto.
eapply IHHtyping; eauto; rewrite /expr_vars -/expr_vars //= in H1; destruct f; destruct x0 => //=;
rewrite //= in H1; rewrite /insert/ctx_insert ?dom_insert; set_solver.
rewrite /expr_vars -/expr_vars //= in H1.
destruct f, x0; set_solver.
eapply IHHtyping1; eauto; unfold_expr_vars; set_solver.
eapply IHHtyping2; eauto; unfold_expr_vars; set_solver.
eapply IHHtyping; eauto; unfold_expr_vars; set_solver.
eapply IHHtyping1; eauto; unfold_expr_vars; set_solver.
eapply IHHtyping2; eauto; unfold_expr_vars; set_solver.
eapply IHHtyping1; eauto; unfold_expr_vars; set_solver.
eapply IHHtyping2; eauto; unfold_expr_vars; set_solver.
unfold_expr_vars; set_solver.
eapply IHHtyping0; eauto; unfold_expr_vars; set_solver.
unfold_expr_vars; set_solver.
eapply IHHtyping0; eauto; unfold_expr_vars; set_solver.
Definition subst_tuple_conv (x : (@subst_tuple disk_op (jrnl_spec_ext) jrnl_ty)) :
twophase_sub_logical_reln_defs.subst_tuple :=
{| twophase_sub_logical_reln_defs.subst_ty := subst_ty x;
twophase_sub_logical_reln_defs.subst_sval := subst_sval x;
twophase_sub_logical_reln_defs.subst_ival := subst_ival x |}.
Definition filtered_subst (Γsubst : gmap string (@subst_tuple disk_op (jrnl_spec_ext) jrnl_ty )) (Γ': Ctx) :=
subst_tuple_conv <$>
(filter (λ x: string * ((@subst_tuple disk_op jrnl_spec_ext jrnl_ty)), is_Some (Γ' !! fst x)) Γsubst).
Lemma binder_delete_filtered_subst Γsubst Γ x :
binder_delete x (filtered_subst Γsubst Γ) = filtered_subst Γsubst (binder_delete x Γ).
rewrite -binder_delete_fmap.
destruct (decide (s = i)).
apply map_lookup_filter_None_2; eauto.
rewrite lookup_delete //=.
rewrite lookup_delete_ne //.
destruct (decide (is_Some (Γ !! i))).
rewrite ?(map_lookup_filter_key_in _ (λ i, is_Some (Γ !! i))) //.
rewrite ?(map_lookup_filter_key_in _ (λ i, is_Some (delete s Γ !! i))) //.
rewrite lookup_delete_ne //.
rewrite ?(map_lookup_filter_key_notin _ (λ i, is_Some (Γ !! i))) //.
rewrite ?(map_lookup_filter_key_notin _ (λ i, is_Some (delete s Γ !! i))) //.
rewrite lookup_delete_ne //.
Lemma binder_delete_filtered_subst2 Γsubst Γ x :
binder_delete x (filtered_subst Γsubst Γ) = filtered_subst (binder_delete x Γsubst) Γ.
rewrite /filtered_subst -fmap_delete map_filter_delete //.
Lemma filtered_subst_lookup1 (Γ' : Ctx) (Γsubst : gmap string (@subst_tuple disk_op (jrnl_spec_ext) jrnl_ty )) i :
is_Some (Γ' !! i) →
filter (λ x : string * ty, is_Some (Γ' !! x.1))
(subst_ty <$> Γsubst) !! i = (subst_ty <$> Γsubst) !! i.
destruct ((subst_ty <$> Γsubst) !! i) eqn:Heq.
apply map_lookup_filter_Some_2; eauto.
apply map_lookup_filter_None_2; eauto.
Notation spec_ty := jrnl_ty.
Notation sty := (@ty (@val_tys _ spec_ty)).
Global Instance styG_twophaseG Σ: (styG (specTy_model := twophaseTy_model JRNL_KIND_SIZE)) Σ → twophaseG Σ.
Lemma atomic_convertible_val_interp {Σ} {hG: heapGS Σ} {hRG : refinement_heapG Σ}
{hS: (styG (specTy_model := twophaseTy_model JRNL_KIND_SIZE)) Σ}
(t : sty) es e dinit objs_dom γ γ' tph_val :
atomic_convertible t →
@val_interp _ _ _ _ _ _ _ _ _ _ hG hRG (twophaseTy_model JRNL_KIND_SIZE) hS t es e ⊢@{_}
atomically_val_interp (htpG := hS) dinit objs_dom γ γ' tph_val t es e.
rewrite /styG in hS * => //=.
rewrite /twophaseTy_model in hS *.
induction t => es e; try (inversion 1; done).
rewrite /val_interp -/val_interp.
iDestruct "H" as (v1 v2 vs1 vs2 (Heq&Heqs)) "H".
iDestruct "H" as "(Hv1&Hv2)".
rewrite /val_interp -/val_interp.
rewrite atomically_val_interp_list_unfold.
iDestruct "H" as (?? Heq) "H".
iExists _, _; iSplit; first eauto.
iInduction lvs as [| v lvs] "IH" forall (lv IHt).
iDestruct "H" as "(Hhd&Htl)".
rewrite /val_interp -/val_interp.
iDestruct "H" as "[H|H]"; iDestruct "H" as (v vs (Heq&Heqs)) "H"; subst; rewrite /=; [ iLeft | iRight ].
rewrite //= /val_interp/twophase_val_interp //=.
Lemma atomically_deconvertible_val_interp `{hG: !heapGS Σ} {hRG : refinement_heapG Σ} {hS: styG Σ}
(t : sty) es e dinit objs_dom γ γ' tph_val :
atomic_deconvertible t →
atomically_val_interp (htpG := (styG_twophaseG _ hS)) dinit objs_dom γ γ' tph_val t es e ⊢@{_}
@val_interp _ _ _ _ _ _ _ _ _ _ hG hRG (twophaseTy_model JRNL_KIND_SIZE) hS t es e.
induction t => es e; try (inversion 1; done).
rewrite /val_interp -/val_interp.
iDestruct "H" as (v1 v2 vs1 vs2 (Heq&Heqs)) "H".
iDestruct "H" as "(Hv1&Hv2)".
rewrite /val_interp -/val_interp.
rewrite atomically_val_interp_list_unfold.
iDestruct "H" as (?? Heq) "H".
iExists _, _; iSplit; first eauto.
iInduction lvs as [| v lvs] "IH" forall (lv).
iDestruct "H" as "(Hhd&Htl)".
rewrite /val_interp -/val_interp.
iDestruct "H" as "[H|H]"; iDestruct "H" as (v vs (Heq&Heqs)) "H"; subst; rewrite /=; [ iLeft | iRight ].
rewrite //= /val_interp/twophase_val_interp //=.
Lemma filtered_subst_projection1 Γsubst Γ' :
(∀ (x : string) (ty0 : ty),
Γ' !! x = Some ty0 →
(subst_ty <$> Γsubst) !! x = Some ty0 ∧ atomic_convertible ty0) →
twophase_sub_logical_reln_defs.subst_ty <$> filtered_subst Γsubst Γ' = Γ'.
rewrite -map_fmap_compose //=.
destruct (Γ' !! i) eqn:Heq.
transitivity (filter (λ x : string * _, is_Some (Γ' !! x.1)) (subst_ty <$> Γsubst) !! i).
rewrite map_filter_fmap //=.
replace (Γ' !! i) with ((subst_ty <$> Γsubst) !! i); last first.
edestruct Hlookup as (Heq'&_); eauto.
apply filtered_subst_lookup1; eauto.
apply map_lookup_filter_None_2; right.
Lemma lookup_binder_insert_ne x y v (m : Ctx) :
x ≠ BNamed y →
<[x := v]> m !! y = m !! y.
destruct x; rewrite //= ?lookup_insert_ne //=; congruence.
Lemma lookup_binder_delete_ne {A} x y (m : gmap _ A) :
x ≠ BNamed y →
binder_delete x m !! y = m !! y.
destruct x; rewrite //= ?lookup_delete_ne //=; congruence.
Lemma filtered_subst_insert_filter Γsubst Γ (x : binder) v :
match x with
| BAnon => True
| BNamed x => Γsubst !! x = None
end →
filtered_subst Γsubst (<[x := v]> Γ) = filtered_subst Γsubst Γ.
rewrite lookup_insert_ne //=.
Lemma subst_map_subtyping_sval' Γsubst Γ' e1 x ebdy t :
(∀ (x : string) (ty0 : sty) ty0',
Γ' !! x = Some ty0 → (subst_ty <$> Γsubst) !! x = Some ty0' → ty0 = ty0' ∧ atomic_convertible ty0) →
atomic_body_expr_transTy Γ' x e1 ebdy t →
(subst_map (subst_sval <$> Γsubst) e1) =
(subst_map (twophase_sub_logical_reln_defs.subst_sval <$> filtered_subst Γsubst Γ') e1).
induction Htrans => Γsubst Hmap; try (rewrite /= ?IHHtrans ?IHHtrans1 ?IHHtrans2 ?IHHtrans3 //=).
rewrite ?lookup_fmap //=.
destruct (Γsubst !! x) eqn:Heq.
edestruct Hmap as (Heq'&Hconv); eauto.
rewrite ?lookup_fmap Heq.
rewrite ?lookup_fmap //=.
erewrite map_lookup_filter_Some_2; eauto.
erewrite map_lookup_filter_None_2; eauto.
rewrite -binder_delete_fmap.
rewrite -binder_delete_fmap.
rewrite -binder_delete_fmap.
rewrite -binder_delete_fmap.
rewrite binder_delete_filtered_subst2.
rewrite binder_delete_filtered_subst2.
rewrite IHHtrans; last first.
destruct (decide (x = BNamed y)).
rewrite //= lookup_delete; naive_solver.
rewrite lookup_binder_delete_ne //.
destruct (decide (f = BNamed y)).
rewrite lookup_delete; naive_solver.
rewrite lookup_binder_delete_ne //.
rewrite ?lookup_binder_insert_ne // in Hlookup.
rewrite ?filtered_subst_insert_filter //=.
rewrite lookup_delete //.
rewrite /= lookup_delete //.
destruct (decide (s0 = s)); subst.
rewrite lookup_delete //.
rewrite lookup_delete_ne // lookup_delete //.
Lemma subst_map_subtyping_sval Γsubst Γ' e1 x ebdy t :
(∀ (x : string) (ty0 : sty),
Γ' !! x = Some ty0 → (subst_ty <$> Γsubst) !! x = Some ty0 ∧ atomic_convertible ty0) →
atomic_body_expr_transTy Γ' x e1 ebdy t →
(subst_map (subst_sval <$> Γsubst) e1) =
(subst_map (twophase_sub_logical_reln_defs.subst_sval <$> filtered_subst Γsubst Γ') e1).
eapply subst_map_subtyping_sval'; eauto.
Lemma subst_map_subtyping_ival' Γsubst Γ' e1 (v : val) ebdy t :
(∀ (x : string) (ty0 : sty) ty0',
Γ' !! x = Some ty0 → (subst_ty <$> Γsubst) !! x = Some ty0' → ty0 = ty0' ∧ atomic_convertible ty0) →
atomic_body_expr_transTy Γ' v e1 ebdy t →
(subst_map (subst_ival <$> Γsubst) ebdy) =
(subst_map (twophase_sub_logical_reln_defs.subst_ival <$> filtered_subst Γsubst Γ') ebdy).
remember (of_val v) as tph eqn:Heq0.
induction Htrans => Γsubst Hmap; try (rewrite /= ?IHHtrans ?IHHtrans1 ?IHHtrans2 ?IHHtrans3 //=).
rewrite ?lookup_fmap //=.
destruct (Γsubst !! x) eqn:Heq.
edestruct Hmap as (Heq'&Hconv); eauto.
rewrite ?lookup_fmap Heq.
rewrite ?lookup_fmap //=.
erewrite map_lookup_filter_Some_2; eauto.
erewrite map_lookup_filter_None_2; eauto.
rewrite -binder_delete_fmap.
rewrite -binder_delete_fmap.
rewrite -binder_delete_fmap.
rewrite -binder_delete_fmap.
rewrite binder_delete_filtered_subst2.
rewrite binder_delete_filtered_subst2.
rewrite IHHtrans; last first.
destruct (decide (x = BNamed y)).
rewrite //= lookup_delete; naive_solver.
rewrite lookup_binder_delete_ne //.
destruct (decide (f = BNamed y)).
rewrite lookup_delete; naive_solver.
rewrite lookup_binder_delete_ne //.
rewrite ?lookup_binder_insert_ne // in Hlookup.
rewrite ?filtered_subst_insert_filter //=.
rewrite lookup_delete //.
rewrite /= lookup_delete //.
destruct (decide (s0 = s)); subst.
rewrite lookup_delete //.
rewrite lookup_delete_ne // lookup_delete //.
Lemma subst_map_subtyping_ival Γsubst Γ' e1 ebdy tph tph_val t :
(∀ (x : string) (ty0 : sty),
Γ' !! x = Some ty0 → (subst_ty <$> Γsubst) !! x = Some ty0 ∧ atomic_convertible ty0) →
atomic_body_expr_transTy Γ' (of_val tph_val) e1 (subst tph tph_val ebdy) t →
(subst_map (subst_ival <$> Γsubst) (subst tph tph_val ebdy)) =
(subst_map (twophase_sub_logical_reln_defs.subst_ival <$> filtered_subst Γsubst Γ') (subst tph tph_val ebdy)).
eapply subst_map_subtyping_ival'; eauto.
Local Definition N := nroot.@"tpref".
Lemma jrnl_atomic_obligation:
@sty_atomic_obligation _ _ disk_semantics _ _ _ _ _ _ (twophaseTy_model JRNL_KIND_SIZE) jrnl_atomic_transTy.
rewrite /sty_atomic_obligation//=.
iIntros (? hG hRG hJrnl el1 el2 tl e1 e2 t Γsubst Htrans) "Hinv #Hspec #Htrace #HΓ HhasTy".
rewrite ?delete_notin; last first.
wpc_bind (subst_map _ el2).
spec_bind (subst_map _ el1) as Hctx.
iDestruct ("HhasTy" with "[//] Hj") as "H".
iApply (wpc_strong_mono with "H"); auto.
iDestruct "Hv" as (vs) "(Hj&Hinterp)".
iDestruct (jrnl_inv_twophase_pre with "[$] [$]") as "H".
iDestruct "H" as (l γ γ' ?? ->) "H".
wp_apply (wp_Txn__Begin' N with "[$]").
iIntros (tph_val) "Hstarted".
apply (atomic_body_expr_subst _ _ _ _ _ #tph_val) in H2; swap 1 3.
rewrite subst_map_subst_comm //; last first.
rewrite dom_fmap in H0 *.
iDestruct (atomically_fundamental_lemma dinit objs_dom γ γ' tph_val Γ') as "Hhas_semTy".
rewrite /twophase_sub_logical_reln_defs.ctx_has_semTy.
iDestruct ("Hhas_semTy" $! (filtered_subst Γsubst Γ') with "[] [$] [] [] [Hstarted]") as "H".
apply filtered_subst_projection1; auto.
iApply big_sepM_fmap => /=.
iApply (big_sepM_mono with "HΓ").
iIntros (k x Hlookup) "Hval Hfilter".
iDestruct "Hfilter" as %(?&Heq).
iApply (@atomic_convertible_val_interp with "Hval").
destruct Heq as (Heq&Hconv).
rewrite /= lookup_fmap Hlookup /= in Heq.
erewrite <-subst_map_subtyping_sval; eauto.
erewrite <-subst_map_subtyping_ival; eauto.
iDestruct (wpc_wp with "H") as "H".
iApply (wp_wand with "H [-]").
iDestruct "Hv" as (vs') "(Hstarted&Hinterp)".
rewrite /op_wrappers.Txn__ConditionalCommit'.
iDestruct "Hinterp" as "[Hnone|Hsome]".
iDestruct "Hnone" as (vsnone vnone (->&->)) "Hunit".
iDestruct "Hunit" as %(->&->).
iDestruct (twophase_started_abort with "Hstarted") as "H".
iApply (wpc_nval_elim_wp with "H"); auto.
wp_apply (wp_Txn__ReleaseAll' with "Hrel").
iDestruct "Hsome" as (vssome vsome (->&->)) "Hv".
rewrite /txn.Txn__Commit.
wp_apply (wp_Txn__commitNoRelease' with "[$]").
iDestruct "H" as "(Hrel&Hj)".
wp_apply (wp_Txn__ReleaseAll' with "[$]").
rewrite /val_interp -/val_interp.
iApply (atomically_deconvertible_val_interp with "Hv"); eauto.
iDestruct "H" as "(Hrel&Hj)".
wp_apply (wp_Txn__ReleaseAll' with "[$]").
rewrite /val_interp -/val_interp.