Timings for refinement.v
- /home/gitlab-runner/builds/v6HyzL39/0/coq/coq/_bench/opam.OLD/ocaml-OLD/.opam-switch/build/coq-iris-examples.dev.2024-04-19.0.5dec292c//./theories/logrel/F_mu_ref_conc/binary/examples/stack/refinement.v.timing
- /home/gitlab-runner/builds/v6HyzL39/0/coq/coq/_bench/opam.NEW/ocaml-NEW/.opam-switch/build/coq-iris-examples.dev.2024-04-19.0.5dec292c//./theories/logrel/F_mu_ref_conc/binary/examples/stack/refinement.v.timing
From iris.algebra Require Import auth list.
From iris.program_logic Require Import adequacy ectxi_language.
From iris_examples.logrel.F_mu_ref_conc.binary Require Import soundness.
From iris_examples.logrel.F_mu_ref_conc.binary.examples Require Import lock.
From iris_examples.logrel.F_mu_ref_conc.binary.examples.stack Require Import
CG_stack FG_stack stack_rules.
From iris.proofmode Require Import proofmode.
From iris.prelude Require Import options.
Definition stackN : namespace := nroot .@ "stack".
Section Stack_refinement.
Context `{heapIG Σ, cfgSG Σ}.
Notation D := (persistent_predO (val * val) (iPropI Σ)).
Implicit Types Δ : listO D.
Lemma FG_CG_counter_refinement :
⊢ [] ⊨ FG_stack ≤log≤ CG_stack : TForall (TProd (TProd
(TArrow (TVar 0) TUnit)
(TArrow TUnit (TSum TUnit (TVar 0))))
(TArrow (TArrow (TVar 0) TUnit) TUnit)).
(* executing the preambles *)
iIntros (Δ [|??]) "!# #[Hspec HΓ]"; iIntros (j K) "Hj"; last first.
iDestruct (interp_env_length with "HΓ") as %[=].
cbn -[FG_stack CG_stack].
rewrite ?empty_env_subst /CG_stack /FG_stack.
iExists (TLamV _); iFrame "Hj".
iIntros (τi j K) "Hj /=".
iMod (do_step_pure with "[$Hj]") as "Hj"; eauto.
iApply wp_pure_step_later; auto.
iMod (steps_newlock _ j (LetInCtx _ :: K) with "[$Hj]")
as (l) "[Hj Hl]"; eauto.
iMod (do_step_pure _ j K with "[$Hj]") as "Hj"; eauto.
iMod (step_alloc _ j (LetInCtx _ :: K) with "[$Hj]")
as (stk') "[Hj Hstk']"; eauto.
iMod (do_step_pure with "[$Hj]") as "Hj"; eauto.
iApply (wp_bind (fill [AllocCtx; AppRCtx (RecV _)]));
iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|].
iApply wp_alloc; first done.
iNext; iIntros (istk) "Histk".
iApply (wp_bind (fill [AppRCtx (RecV _)]));
iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|].
iApply wp_alloc; first done.
iNext; iIntros (stk) "Hstk".
iApply wp_pure_step_later; trivial.
iMod (pointsto_persist with "Histk") as "#Histk".
(* establishing the invariant *)
iAssert (StackLink τi (LocV istk, FoldV (InjLV UnitV))) with "[]" as "HLK".
rewrite StackLink_unfold.
iAssert ((∃ istk v, stk' ↦ₛ v
∗ stk ↦ᵢ (LocV istk)
∗ StackLink τi (LocV istk, v)
∗ l ↦ₛ (#♭v false)
)%I) with "[Hstk Hstk' HLK Hl]" as "Hinv".
by iFrame "Hstk' Hstk Hl HLK".
iMod (inv_alloc stackN with "[Hinv]") as "#Hinv"; [iNext; iExact "Hinv"|].
iClear (istk) "Histk HLK".
iApply wp_value; simpl; trivial.
iExists (PairV (PairV (CG_locked_pushV _ _) (CG_locked_popV _ _)) (LamV _)).
rewrite CG_locked_push_of_val CG_locked_pop_of_val.
Local Transparent CG_snap_iter.
iExists (_, _), (_, _); iSplit; eauto.
(* refinement of push and pop *)
iExists (_, _), (_, _); iSplit; eauto.
iIntros ( [v1 v2] ) "#Hrel".
rewrite -(FG_push_folding (Loc stk)).
rewrite {2}(FG_push_folding (Loc stk)).
iApply wp_pure_step_later; auto using to_of_val.
rewrite -(FG_push_folding (Loc stk)).
iApply (wp_bind (fill [LetInCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|].
iInv stackN as (istk v) "[Hstk' [Hstk [HLK Hl]]]" "Hclose".
iApply (wp_load with "Hstk").
iMod ("Hclose" with "[Hstk' HLK Hl Hstk]") as "_".
iExists _, _; by iFrame "Hstk' HLK Hl Hstk".
iApply wp_pure_step_later; auto using to_of_val.
iApply (wp_bind (fill [CasRCtx (LocV _) (LocV _); IfCtx _ _]));
iApply wp_wand_l; iSplitR; [iIntros (w) "Hw"; iExact "Hw"|].
iApply wp_alloc; simpl; trivial.
iApply (wp_bind (fill [IfCtx _ _]));
iApply wp_wand_l; iSplitR; [iIntros (w) "H"; iExact "H"|].
iInv stackN as (istk2 v) "[Hstk' [Hstk [HLK Hl]]]" "Hclose".
(* deciding whether CAS will succeed or fail *)
destruct (decide (istk = istk2)) as [|Hneq]; subst.
(* CAS succeeds *)
(* In this case, the specification pushes *)
iMod (steps_CG_locked_push _ j K with "[Hj Hl Hstk']")
as "[Hj [Hstk' Hl]]"; first solve_ndisj.
rewrite CG_locked_push_of_val.
by iFrame "Hspec Hstk' Hj".
iApply (wp_cas_suc with "Hstk"); auto.
iMod (pointsto_persist with "Hltmp") as "#Hltmp".
iMod ("Hclose" with "[-Hj]") as "_".
do 2 rewrite StackLink_unfold.
rewrite -StackLink_unfold.
iApply wp_pure_step_later; auto.
iIntros "!> _"; iApply wp_value; trivial.
iApply (wp_cas_fail with "Hstk"); auto; first congruence.
iMod ("Hclose" with "[-Hj]").
by iFrame "Hstk' Hstk Hl".
iApply wp_pure_step_later; auto.
iIntros ( [v1 v2] ) "[% %]".
iIntros (j K) "Hj /="; simplify_eq/=.
rewrite -(FG_pop_folding (Loc stk)).
rewrite {2}(FG_pop_folding (Loc stk)).
iApply wp_pure_step_later; auto.
rewrite -(FG_pop_folding (Loc stk)).
iApply (wp_bind (fill [LetInCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|].
iInv stackN as (istk v) "[Hstk' [Hstk [#HLK Hl]]]" "Hclose".
iApply (wp_load with "Hstk").
iPoseProof "HLK" as "HLK'".
(* Checking whether the stack is empty *)
rewrite {2}StackLink_unfold.
iDestruct "HLK'" as (istk2 w) "[% [Hmpt [[% %]|HLK']]]"; simplify_eq/=.
rewrite CG_locked_pop_of_val.
iMod (steps_CG_locked_pop_fail with "[$Hspec $Hstk' $Hl $Hj]")
as "[Hj [Hstk' Hl]]"; first solve_ndisj.
iMod ("Hclose" with "[-Hj Hmpt]") as "_".
by iFrame "Hstk' Hstk Hl".
iApply wp_pure_step_later; auto.
iApply (wp_bind (fill [LetInCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (w) "Hw"; iExact "Hw"|].
iInv stackN as (istk3 w) "[Hstk' [Hstk [HLK Hl]]]" "Hclose".
iApply (wp_load with "Hmpt").
iMod ("Hclose" with "[-Hj]") as "_".
iFrame "Hstk' Hstk HLK Hl".
iApply wp_pure_step_later; simpl; trivial.
iApply wp_pure_step_later; trivial.
iApply wp_value; simpl; trivial.
iExists (_, _); repeat iSplit; simpl; trivial.
(* The stack is not empty *)
iMod ("Hclose" with "[-Hj Hmpt HLK']") as "_".
by iFrame "Hstk' Hstk HLK Hl".
iApply wp_pure_step_later; auto.
iApply (wp_bind (fill [LetInCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (w') "Hw"; iExact "Hw"|].
iInv stackN as (istk3 w') "[Hstk' [Hstk [HLK Hl]]]" "Hclose".
iApply (wp_load with "Hmpt").
iMod ("Hclose" with "[-Hj Hmpt HLK']") as "_".
by iFrame "Hstk' Hstk HLK Hl".
iApply wp_pure_step_later; auto.
iDestruct "HLK'" as (y1 z1 y2 z2) "[% HLK']".
iApply wp_pure_step_later; first done.
iApply (wp_bind (fill [UnfoldCtx; CasRCtx (LocV _) (LocV _); IfCtx _ _]));
iApply wp_wand_l; iSplitR; [iIntros (w) "Hw"; iExact "Hw"|].
iApply wp_pure_step_later; auto.
iApply (wp_bind (fill [CasRCtx (LocV _) (LocV _); IfCtx _ _]));
iApply wp_wand_l; iSplitR; [iIntros (w) "Hw"; iExact "Hw"|].
iApply wp_pure_step_later; auto.
iApply (wp_bind (fill [IfCtx _ _]));
iApply wp_wand_l; iSplitR; [iIntros (w) "Hw"; iExact "Hw"|].
iInv stackN as (istk3 w) "[Hstk' [Hstk [#HLK Hl]]]" "Hclose".
(* deciding whether CAS will succeed or fail *)
destruct (decide (istk2 = istk3)) as [|Hneq]; subst.
(* CAS succeeds *)
(* In this case, the specification pushes *)
iApply (wp_cas_suc with "Hstk"); simpl; auto.
iPoseProof "HLK" as "HLK'".
rewrite {2}StackLink_unfold.
iDestruct "HLK'" as (istk4 w2) "[% [Hmpt' HLK']]"; simplify_eq/=.
iDestruct (pointsto_agree with "Hmpt Hmpt'") as %<-.
iDestruct "HLK'" as "[[% %]|HLK']"; simplify_eq/=.
iDestruct "HLK'" as (yn1 yn2 zn1 zn2)
"[% [% [#Hrel HLK'']]]"; simplify_eq/=.
(* Now we have proven that specification can also pop. *)
rewrite CG_locked_pop_of_val.
iMod (steps_CG_locked_pop_suc with "[$Hspec $Hstk' $Hl $Hj]")
as "[Hj [Hstk' Hl]]"; first solve_ndisj.
iMod ("Hclose" with "[-Hj]") as "_".
iIntros "{Hmpt Hmpt' HLK}".
rewrite StackLink_unfold.
iDestruct "HLK''" as (istk5 w2) "[% [Hmpt HLK]]"; simplify_eq/=.
rewrite StackLink_unfold.
iExists _, _; iSplitR; trivial.
iApply wp_pure_step_later; auto.
iApply (wp_bind (fill [InjRCtx])); iApply wp_wand_l;
iSplitR; [iIntros (w) "Hw"; iExact "Hw"|].
iApply wp_pure_step_later; auto.
iExists (InjRV _); iFrame "Hj".
iApply (wp_cas_fail with "Hstk"); [rewrite /= ?to_of_val //; congruence..|].
iMod ("Hclose" with "[-Hj]") as "_".
by iFrame "Hstk' Hstk HLK Hl".
iApply wp_pure_step_later; auto.
iIntros ( [f1 f2] ) "/= #Hfs".
iApply wp_pure_step_later; auto using to_of_val.
iMod (do_step_pure with "[$Hspec $Hj]") as "Hj"; eauto.
replace (FG_iter (of_val f1)) with (of_val (FG_iterV (of_val f1)))
by (by rewrite FG_iter_of_val).
replace (CG_iter (of_val f2)) with (of_val (CG_iterV (of_val f2)))
by (by rewrite CG_iter_of_val).
iApply (wp_bind (fill [FoldCtx; AppRCtx _])); iApply wp_wand_l;
iSplitR; [iIntros (w) "Hw"; iExact "Hw"|].
iInv stackN as (istk3 w) "[>Hstk' [>Hstk [#HLK >Hl]]]" "Hclose".
iMod (steps_CG_snap _ _ (AppRCtx _ :: K)
with "[Hstk' Hj Hl]") as "[Hj [Hstk' Hl]]"; first solve_ndisj.
by iFrame "Hspec Hstk' Hl Hj".
iApply (wp_load with "[$Hstk]").
iMod ("Hclose" with "[-Hj]") as "_".
iExists _, _; by iFrame "Hstk' Hstk HLK Hl".
rewrite ?fill_app /= -FG_iter_folding.
iLöb as "Hlat" forall (istk3 w) "HLK".
rewrite {2}FG_iter_folding.
iApply wp_pure_step_later; simpl; trivial.
rewrite -FG_iter_folding.
iApply (wp_bind (fill [LoadCtx; CaseCtx _ _])); iApply wp_wand_l;
iSplitR; [iIntros (v) "Hw"; iExact "Hw"|].
iApply wp_pure_step_later; trivial.
iApply (wp_bind (fill [CaseCtx _ _])); iApply wp_wand_l;
iSplitR; [iIntros (v) "Hw"; iExact "Hw"|].
rewrite StackLink_unfold.
iDestruct "HLK" as (istk4 v) "[% [Hmpt HLK]]"; simplify_eq/=.
iInv stackN as (istk5 v') "[Hstk' [Hstk [HLK' Hl]]]" "Hclose".
iApply (wp_load with "Hmpt").
iDestruct "HLK" as "[[% %]|HLK'']"; simplify_eq/=.
iMod (steps_CG_iter_end with "[$Hspec $Hj]") as "Hj"; first solve_ndisj.
iMod ("Hclose" with "[-Hj]").
by iFrame "Hstk' Hstk Hl".
iApply wp_pure_step_later; trivial.
iApply wp_value; trivial.
iDestruct "HLK''" as (yn1 yn2 zn1 zn2)
"[% [% [#Hrel HLK'']]]"; simplify_eq/=.
iMod (steps_CG_iter with "[$Hspec $Hj]") as "Hj"; first solve_ndisj.
iMod ("Hclose" with "[-Hj HLK'']") as "_".
by iFrame "Hstk' Hstk Hl".
iApply wp_pure_step_later; simpl; rewrite ?to_of_val; trivial.
iApply (wp_bind (fill [AppRCtx _; SeqCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (w') "Hw"; iExact "Hw"|].
iApply wp_pure_step_later; simpl; rewrite ?to_of_val; trivial.
iApply (wp_bind (fill [SeqCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (w') "Hw"; iExact "Hw"|].
rewrite StackLink_unfold.
iDestruct "HLK''" as (istk6 w') "[% HLK]"; simplify_eq/=.
iSpecialize ("Hfs" $! (yn1, zn1) with "Hrel").
iSpecialize ("Hfs" $! _ (SeqCtx _ :: K)).
iApply wp_wand_l; iSplitR "Hj"; [|iApply "Hfs"; by iFrame "#"].
iIntros (u) "/="; iDestruct 1 as (z) "[Hj [% %]]".
iMod (do_step_pure with "[$Hspec $Hj]") as "Hj"; [done..|].
replace (CG_iter (of_val f2)) with (of_val (CG_iterV (of_val f2)))
by (by rewrite CG_iter_of_val).
iMod (step_snd _ _ (AppRCtx _ :: K) with "[$Hspec Hj]") as "Hj";
[| | |simpl; by iFrame "Hj"|]; rewrite ?to_of_val; auto.
iApply wp_pure_step_later; trivial.
replace (FG_iter (of_val f1)) with (of_val (FG_iterV (of_val f1)))
by (by rewrite FG_iter_of_val).
iApply (wp_bind (fill [AppRCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (w'') "Hw"; iExact "Hw"|].
iApply wp_pure_step_later; auto using to_of_val.
rewrite -FG_iter_folding.
iApply ("Hlat" $! istk6 zn2 with "[Hj] [HLK]"); trivial.
rewrite StackLink_unfold; iModIntro; simpl.
iDestruct "HLK" as "[Histk6 [HLK|HLK]]";
iExists istk6, w'; iSplit; auto.
iDestruct "HLK" as (? ? ? ?) "(?&?&?&?)".
Theorem stack_ctx_refinement :
[] ⊨ FG_stack ≤ctx≤ CG_stack : TForall (TProd (TProd
(TArrow (TVar 0) TUnit)
(TArrow TUnit (TSum TUnit (TVar 0))))
(TArrow (TArrow (TVar 0) TUnit) TUnit)).
set (Σ := #[invΣ; gen_heapΣ loc val; soundness_binaryΣ]).
set (HG := soundness.HeapPreIG Σ _ _).
eapply (binary_soundness Σ); eauto using FG_stack_type, CG_stack_type.
intros; apply FG_CG_counter_refinement.