Commit 76c60e8f authored by Amin Timany's avatar Amin Timany

Simplify stack programs

parent f72453a9
...@@ -7,20 +7,26 @@ Definition newlock : expr := Alloc (#♭ false). ...@@ -7,20 +7,26 @@ Definition newlock : expr := Alloc (#♭ false).
Definition acquire : expr := Definition acquire : expr :=
Rec (If (CAS (Var 1) (# false) (# true)) (Unit) (App (Var 0) (Var 1))). Rec (If (CAS (Var 1) (# false) (# true)) (Unit) (App (Var 0) (Var 1))).
(** [release = λ x. x <- false] *) (** [release = λ x. x <- false] *)
Definition release : expr := Rec (Store (Var 1) (# false)). Definition release : expr := Lam (Store (Var 0) (# false)).
(** [with_lock e l = λ x. (acquire l) ;; e x ;; (release l)] *) (** [with_lock e l = λ x. (acquire l) ;; e x ;; (release l)] *)
Definition with_lock (e : expr) (l : expr) : expr := Definition with_lock (e : expr) (l : expr) : expr :=
Rec Lam
(App (Rec (App (Rec (App (Rec (Var 3)) (App release l.[ren (+6)]))) (Seq
(App e.[ren (+4)] (Var 3)))) (App acquire l.[ren (+1)])
(App acquire l.[ren (+2)]) (LetIn
(App e.[ren (+1)] (Var 0))
(Seq (App release l.[ren (+2)]) (Var 0))
)
). ).
Definition with_lockV (e l : expr) : val := Definition with_lockV (e l : expr) : val :=
RecV LamV
(App (Rec (App (Rec (App (Rec (Var 3)) (App release l.[ren (+6)]))) (Seq
(App e.[ren (+4)] (Var 3)))) (App acquire l.[ren (+1)])
(App acquire l.[ren (+2)]) (LetIn
(App e.[ren (+1)] (Var 0))
(Seq (App release l.[ren (+2)]) (Var 0))
)
). ).
Lemma with_lock_to_val e l : to_val (with_lock e l) = Some (with_lockV e l). Lemma with_lock_to_val e l : to_val (with_lock e l) = Some (with_lockV e l).
...@@ -29,6 +35,7 @@ Proof. trivial. Qed. ...@@ -29,6 +35,7 @@ Proof. trivial. Qed.
Lemma with_lock_of_val e l : of_val (with_lockV e l) = with_lock e l. Lemma with_lock_of_val e l : of_val (with_lockV e l) = with_lock e l.
Proof. trivial. Qed. Proof. trivial. Qed.
Global Typeclasses Opaque with_lockV.
Global Opaque with_lockV. Global Opaque with_lockV.
Lemma newlock_closed f : newlock.[f] = newlock. Lemma newlock_closed f : newlock.[f] = newlock.
...@@ -43,15 +50,10 @@ Lemma release_closed f : release.[f] = release. ...@@ -43,15 +50,10 @@ Lemma release_closed f : release.[f] = release.
Proof. by asimpl. Qed. Proof. by asimpl. Qed.
Hint Rewrite release_closed : autosubst. Hint Rewrite release_closed : autosubst.
Lemma with_lock_subst (e l : expr) f : (with_lock e l).[f] = with_lock e.[f] l.[f]. Lemma with_lock_subst (e l : expr) f :
(with_lock e l).[f] = with_lock e.[f] l.[f].
Proof. unfold with_lock; asimpl; trivial. Qed. Proof. unfold with_lock; asimpl; trivial. Qed.
Lemma with_lock_closed e l:
( f : var expr, e.[f] = e)
( f : var expr, l.[f] = l)
f, (with_lock e l).[f] = with_lock e l.
Proof. asimpl => H1 H2 f. unfold with_lock. by rewrite ?H1 ?H2. Qed.
Definition LockType := Tref TBool. Definition LockType := Tref TBool.
Lemma newlock_type Γ : typed Γ newlock LockType. Lemma newlock_type Γ : typed Γ newlock LockType.
...@@ -68,18 +70,20 @@ Lemma with_lock_type e l Γ τ τ' : ...@@ -68,18 +70,20 @@ Lemma with_lock_type e l Γ τ τ' :
typed Γ l LockType typed Γ l LockType
typed Γ (with_lock e l) (TArrow τ τ'). typed Γ (with_lock e l) (TArrow τ τ').
Proof. Proof.
intros H1 H2. do 3 econstructor; eauto. intros ??.
- repeat (econstructor; eauto using release_type). do 3 econstructor; eauto using acquire_type.
+ eapply (context_weakening [_; _; _; _; _; _]); eauto. - eapply (context_weakening [_]); eauto.
+ eapply (context_weakening [_; _; _; _]); eauto. - econstructor; eauto using typed.
- eapply acquire_type. eapply (context_weakening [_]); eauto.
- eapply (context_weakening [_; _]); eauto. - econstructor; eauto using typed.
econstructor; eauto using release_type.
eapply (context_weakening [_;_]); eauto.
Qed. Qed.
Section proof. Section proof.
Context `{cfgSG Σ}. Context `{cfgSG Σ}.
Context `{heapIG Σ}. Context `{heapIG Σ}.
Lemma steps_newlock E ρ j K : Lemma steps_newlock E ρ j K :
nclose specN E nclose specN E
spec_ctx ρ j fill K newlock spec_ctx ρ j fill K newlock
...@@ -89,6 +93,7 @@ Section proof. ...@@ -89,6 +93,7 @@ Section proof.
by iMod (step_alloc _ _ j K with "[Hj]") as "Hj"; eauto. by iMod (step_alloc _ _ j K with "[Hj]") as "Hj"; eauto.
Qed. Qed.
Global Typeclasses Opaque newlock.
Global Opaque newlock. Global Opaque newlock.
Lemma steps_acquire E ρ j K l : Lemma steps_acquire E ρ j K l :
...@@ -107,6 +112,7 @@ Section proof. ...@@ -107,6 +112,7 @@ Section proof.
Unshelve. all:trivial. Unshelve. all:trivial.
Qed. Qed.
Global Typeclasses Opaque acquire.
Global Opaque acquire. Global Opaque acquire.
Lemma steps_release E ρ j K l b: Lemma steps_release E ρ j K l b:
...@@ -115,48 +121,45 @@ Section proof. ...@@ -115,48 +121,45 @@ Section proof.
|={E}=> j fill K Unit l ↦ₛ (#v false). |={E}=> j fill K Unit l ↦ₛ (#v false).
Proof. Proof.
iIntros (HNE) "[#Hspec [Hl Hj]]". unfold release. iIntros (HNE) "[#Hspec [Hl Hj]]". unfold release.
iMod (step_rec _ _ j K with "[Hj]") as "Hj"; eauto; try done. iMod (do_step_pure with "[$Hj]") as "Hj"; eauto; try done.
iMod (step_store _ _ j K _ _ _ _ _ with "[Hj Hl]") as "[Hj Hl]"; eauto. iMod (step_store with "[$Hj $Hl]") as "[Hj Hl]"; eauto.
{ by iFrame. }
by iIntros "!> {$Hj $Hl}". by iIntros "!> {$Hj $Hl}".
Unshelve. all: trivial.
Qed. Qed.
Global Typeclasses Opaque release.
Global Opaque release. Global Opaque release.
Lemma steps_with_lock E ρ j K e l P Q v w: Lemma steps_with_lock E ρ j K e l P Q v w:
nclose specN E nclose specN E
( f, e.[f] = e) (* e is a closed term *) (* (∀ f, e.[f] = e) (* e is a closed term *) → *)
( K', spec_ctx ρ P j fill K' (App e (of_val w)) ( K', spec_ctx ρ P j fill K' (App e (of_val w))
|={E}=> j fill K' (of_val v) Q) |={E}=> j fill K' (of_val v) Q)
spec_ctx ρ P l ↦ₛ (#v false) spec_ctx ρ P l ↦ₛ (#v false)
j fill K (App (with_lock e (Loc l)) (of_val w)) j fill K (App (with_lock e (Loc l)) (of_val w))
|={E}=> j fill K (of_val v) Q l ↦ₛ (#v false). |={E}=> j fill K (of_val v) Q l ↦ₛ (#v false).
Proof. Proof.
iIntros (HNE H1 H2) "[#Hspec [HP [Hl Hj]]]". iIntros (HNE He) "[#Hspec [HP [Hl Hj]]]".
iMod (step_rec _ _ j K _ _ _ _ with "[Hj]") as "Hj"; eauto. iMod (do_step_pure with "[$Hj]") as "Hj"; eauto.
iAsimpl. rewrite H1. iAsimpl.
iMod (steps_acquire _ _ j ((AppRCtx (RecV _)) :: K) iMod (steps_acquire _ _ j (SeqCtx _ :: K) with "[$Hj Hl]") as "[Hj Hl]";
_ _ with "[Hj Hl]") as "[Hj Hl]"; eauto. auto. simpl.
{ simpl. iFrame "Hspec Hj Hl"; eauto. } iMod (do_step_pure with "[$Hj]") as "Hj"; eauto.
simpl. iMod (He (LetInCtx _ :: K) with "[$Hj HP]") as "[Hj HQ]"; eauto.
iMod (step_rec _ _ j K _ _ _ _ with "[Hj]") as "Hj"; eauto.
iAsimpl. rewrite H1.
iMod (H2 ((AppRCtx (RecV _)) :: K) with "[Hj HP]") as "[Hj HQ]"; eauto.
{ simpl. iFrame "Hspec Hj HP"; eauto. }
simpl. simpl.
iMod (step_rec _ _ j K _ _ _ _ with "[Hj]") as "Hj"; eauto. iMod (do_step_pure with "[$Hj]") as "Hj"; eauto.
iAsimpl. iAsimpl.
iMod (steps_release _ _ j ((AppRCtx (RecV _)) :: K) _ _ with "[Hj Hl]") iMod (steps_release _ _ j (SeqCtx _ :: K) _ _ with "[$Hj $Hl]")
as "[Hj Hl]"; eauto. as "[Hj Hl]"; eauto.
{ simpl. by iFrame. } simpl.
rewrite ?fill_app /=. iMod (do_step_pure with "[$Hj]") as "Hj"; eauto.
iMod (step_rec _ _ j K _ _ _ _ with "[Hj]") as "Hj"; eauto. iModIntro; by iFrame.
iAsimpl. iModIntro; by iFrame.
Unshelve.
all: try match goal with |- to_val _ = _ => auto using to_of_val end.
trivial.
Qed. Qed.
Global Typeclasses Opaque with_lock.
Global Opaque with_lock. Global Opaque with_lock.
End proof. End proof.
Global Hint Rewrite newlock_closed : autosubst.
Global Hint Rewrite acquire_closed : autosubst.
Global Hint Rewrite release_closed : autosubst.
Global Hint Rewrite with_lock_subst : autosubst.
...@@ -21,27 +21,23 @@ Section Stack_refinement. ...@@ -21,27 +21,23 @@ Section Stack_refinement.
Proof. Proof.
(* executing the preambles *) (* executing the preambles *)
iIntros (Δ [|??] ρ ?) "#[Hspec HΓ]"; iIntros (j K) "Hj"; last first. iIntros (Δ [|??] ρ ?) "#[Hspec HΓ]"; iIntros (j K) "Hj"; last first.
{ iDestruct (interp_env_length with "HΓ") as %[=]. } { iDestruct (interp_env_length with "HΓ") as %[=]. }
iClear "HΓ". cbn -[FG_stack CG_stack]. iClear "HΓ". cbn -[FG_stack CG_stack].
rewrite ?empty_env_subst /CG_stack /FG_stack. rewrite ?empty_env_subst /CG_stack /FG_stack.
iApply wp_value; eauto. iApply wp_value; eauto.
iExists (TLamV _); iFrame "Hj". iExists (TLamV _); iFrame "Hj".
clear j K. iAlways. iIntros (τi) "%". iIntros (j K) "Hj /=". clear j K. iAlways. iIntros (τi) "%". iIntros (j K) "Hj /=".
iMod (step_tlam _ _ j K with "[Hj]") as "Hj"; eauto. iMod (do_step_pure with "[$Hj]") as "Hj"; eauto.
iApply wp_pure_step_later; auto. iNext. iApply wp_pure_step_later; auto. iNext.
iMod (steps_newlock _ _ j (AppRCtx (RecV _) :: K) with "[Hj]") iMod (steps_newlock _ _ j (LetInCtx _ :: K) with "[$Hj]")
as (l) "[Hj Hl]"; eauto. as (l) "[Hj Hl]"; eauto.
iMod (step_rec _ _ j K with "[$Hj]") as "Hj"; eauto. iMod (do_step_pure _ _ j K with "[$Hj]") as "Hj"; eauto.
simpl.
rewrite CG_locked_push_subst CG_locked_pop_subst
CG_iter_subst CG_snap_subst.
simpl. iAsimpl. simpl. iAsimpl.
iMod (step_alloc _ _ j (AppRCtx (RecV _) :: K) with "[Hj]") iMod (step_alloc _ _ j (LetInCtx _ :: K) with "[$Hj]")
as (stk') "[Hj Hstk']"; [| |simpl; by iFrame|]; auto. as (stk') "[Hj Hstk']"; eauto.
iMod (step_rec _ _ j K with "[$Hj]") as "Hj"; eauto.
simpl. simpl.
rewrite CG_locked_push_subst CG_locked_pop_subst iMod (do_step_pure with "[$Hj]") as "Hj"; eauto.
CG_iter_subst CG_snap_subst. simpl. iAsimpl. iAsimpl.
iApply (wp_bind (fill [AllocCtx; AppRCtx (RecV _)])); iApply (wp_bind (fill [AllocCtx; AppRCtx (RecV _)]));
iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|]. iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|].
iApply wp_alloc; first done. iNext; iIntros (istk) "Histk". iApply wp_alloc; first done. iNext; iIntros (istk) "Histk".
...@@ -49,7 +45,7 @@ Section Stack_refinement. ...@@ -49,7 +45,7 @@ Section Stack_refinement.
iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|]. iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|].
iApply wp_alloc; first done. iNext; iIntros (stk) "Hstk". iApply wp_alloc; first done. iNext; iIntros (stk) "Hstk".
simpl. iApply wp_pure_step_later; trivial. iNext. simpl. simpl. iApply wp_pure_step_later; trivial. iNext. simpl.
rewrite FG_push_subst FG_pop_subst FG_iter_subst. simpl. iAsimpl. iAsimpl.
(* establishing the invariant *) (* establishing the invariant *)
iMod (own_alloc ( ( : stackUR))) as (γ) "Hemp"; first done. iMod (own_alloc ( ( : stackUR))) as (γ) "Hemp"; first done.
set (istkG := StackG _ _ γ). set (istkG := StackG _ _ γ).
...@@ -75,8 +71,11 @@ Section Stack_refinement. ...@@ -75,8 +71,11 @@ Section Stack_refinement.
Opaque stack_owns. Opaque stack_owns.
(* splitting *) (* splitting *)
iApply wp_value; simpl; trivial. iApply wp_value; simpl; trivial.
iExists (PairV (PairV (CG_locked_pushV _ _) (CG_locked_popV _ _)) (RecV _)). iExists (PairV (PairV (CG_locked_pushV _ _) (CG_locked_popV _ _)) (LamV _)).
simpl. rewrite CG_locked_push_of_val CG_locked_pop_of_val. iFrame "Hj". simpl. iAsimpl.
rewrite CG_locked_push_of_val CG_locked_pop_of_val.
Transparent CG_snap_iter.
iFrame "Hj".
iExists (_, _), (_, _); iSplit; eauto. iExists (_, _), (_, _); iSplit; eauto.
iSplit. iSplit.
(* refinement of push and pop *) (* refinement of push and pop *)
...@@ -90,7 +89,7 @@ Section Stack_refinement. ...@@ -90,7 +89,7 @@ Section Stack_refinement.
iNext. iNext.
rewrite -(FG_push_folding (Loc stk)). rewrite -(FG_push_folding (Loc stk)).
iAsimpl. iAsimpl.
iApply (wp_bind (fill [AppRCtx (RecV _)])); iApply (wp_bind (fill [LetInCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|]. iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|].
iInv stackN as (istk v h) "[Hoe [Hstk' [Hstk [HLK Hl]]]]" "Hclose". iInv stackN as (istk v h) "[Hoe [Hstk' [Hstk [HLK Hl]]]]" "Hclose".
iApply (wp_load with "Hstk"). iNext. iIntros "Hstk". iApply (wp_load with "Hstk"). iNext. iIntros "Hstk".
...@@ -140,7 +139,7 @@ Section Stack_refinement. ...@@ -140,7 +139,7 @@ Section Stack_refinement.
iApply wp_pure_step_later; auto. iNext. iApply wp_pure_step_later; auto. iNext.
rewrite -(FG_pop_folding (Loc stk)). rewrite -(FG_pop_folding (Loc stk)).
iAsimpl. iAsimpl.
iApply (wp_bind (fill [AppRCtx (RecV _)])); iApply (wp_bind (fill [LetInCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|]. iApply wp_wand_l; iSplitR; [iIntros (v) "Hv"; iExact "Hv"|].
iInv stackN as (istk v h) "[Hoe [Hstk' [Hstk [#HLK Hl]]]]" "Hclose". iInv stackN as (istk v h) "[Hoe [Hstk' [Hstk [#HLK Hl]]]]" "Hclose".
iApply (wp_load with "Hstk"). iNext. iIntros "Hstk". iApply (wp_load with "Hstk"). iNext. iIntros "Hstk".
...@@ -149,6 +148,7 @@ Section Stack_refinement. ...@@ -149,6 +148,7 @@ Section Stack_refinement.
rewrite {2}StackLink_unfold. rewrite {2}StackLink_unfold.
iDestruct "HLK'" as (istk2 w) "[% [Hmpt [[% %]|HLK']]]"; simplify_eq/=. iDestruct "HLK'" as (istk2 w) "[% [Hmpt [[% %]|HLK']]]"; simplify_eq/=.
* (* The stack is empty *) * (* The stack is empty *)
rewrite CG_locked_pop_of_val.
iMod (steps_CG_locked_pop_fail with "[$Hspec $Hstk' $Hl $Hj]") iMod (steps_CG_locked_pop_fail with "[$Hspec $Hstk' $Hl $Hj]")
as "[Hj [Hstk' Hl]]"; first solve_ndisj. as "[Hj [Hstk' Hl]]"; first solve_ndisj.
iMod ("Hclose" with "[-Hj Hmpt]") as "_". iMod ("Hclose" with "[-Hj Hmpt]") as "_".
...@@ -156,7 +156,7 @@ Section Stack_refinement. ...@@ -156,7 +156,7 @@ Section Stack_refinement.
iModIntro. iModIntro.
iApply wp_pure_step_later; auto. iNext. iAsimpl. iApply wp_pure_step_later; auto. iNext. iAsimpl.
clear h. clear h.
iApply (wp_bind (fill [AppRCtx (RecV _)])); iApply (wp_bind (fill [LetInCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (w) "Hw"; iExact "Hw"|]. iApply wp_wand_l; iSplitR; [iIntros (w) "Hw"; iExact "Hw"|].
iClear "HLK". iClear "HLK".
iInv stackN as (istk3 w h) "[Hoe [Hstk' [Hstk [HLK Hl]]]]" "Hclose". iInv stackN as (istk3 w h) "[Hoe [Hstk' [Hstk [HLK Hl]]]]" "Hclose".
...@@ -176,7 +176,7 @@ Section Stack_refinement. ...@@ -176,7 +176,7 @@ Section Stack_refinement.
iModIntro. iApply wp_pure_step_later; auto. iModIntro. iApply wp_pure_step_later; auto.
iNext. iAsimpl. iNext. iAsimpl.
clear h. clear h.
iApply (wp_bind (fill [AppRCtx (RecV _)])); iApply (wp_bind (fill [LetInCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (w') "Hw"; iExact "Hw"|]. iApply wp_wand_l; iSplitR; [iIntros (w') "Hw"; iExact "Hw"|].
iClear "HLK". iClear "HLK".
iInv stackN as (istk3 w' h) "[Hoe [Hstk' [Hstk [HLK Hl]]]]" "Hclose". iInv stackN as (istk3 w' h) "[Hoe [Hstk' [Hstk [HLK Hl]]]]" "Hclose".
...@@ -241,8 +241,8 @@ Section Stack_refinement. ...@@ -241,8 +241,8 @@ Section Stack_refinement.
- (* refinement of iter *) - (* refinement of iter *)
iAlways. clear j K. iIntros ( [f1 f2] ) "/= #Hfs". iIntros (j K) "Hj". iAlways. clear j K. iIntros ( [f1 f2] ) "/= #Hfs". iIntros (j K) "Hj".
iApply wp_pure_step_later; auto using to_of_val. iNext. iApply wp_pure_step_later; auto using to_of_val. iNext.
iMod (step_rec with "[$Hspec $Hj]") as "Hj"; [by rewrite to_of_val|solve_ndisj|]. iMod (do_step_pure with "[$Hspec $Hj]") as "Hj"; eauto.
iAsimpl. rewrite FG_iter_subst CG_snap_subst CG_iter_subst. iAsimpl. iAsimpl.
replace (FG_iter (of_val f1)) with (of_val (FG_iterV (of_val f1))) replace (FG_iter (of_val f1)) with (of_val (FG_iterV (of_val f1)))
by (by rewrite FG_iter_of_val). by (by rewrite FG_iter_of_val).
replace (CG_iter (of_val f2)) with (of_val (CG_iterV (of_val f2))) replace (CG_iter (of_val f2)) with (of_val (CG_iterV (of_val f2)))
...@@ -261,7 +261,7 @@ Section Stack_refinement. ...@@ -261,7 +261,7 @@ Section Stack_refinement.
iLöb as "Hlat" forall (istk3 w) "HLK". iLöb as "Hlat" forall (istk3 w) "HLK".
rewrite {2}FG_iter_folding. rewrite {2}FG_iter_folding.
iApply wp_pure_step_later; simpl; trivial. iApply wp_pure_step_later; simpl; trivial.
rewrite -FG_iter_folding. iAsimpl. rewrite FG_iter_subst. rewrite -FG_iter_folding. iAsimpl.
iNext. iNext.
iApply (wp_bind (fill [LoadCtx; CaseCtx _ _])); iApply wp_wand_l; iApply (wp_bind (fill [LoadCtx; CaseCtx _ _])); iApply wp_wand_l;
iSplitR; [iIntros (v) "Hw"; iExact "Hw"|]. iSplitR; [iIntros (v) "Hw"; iExact "Hw"|].
...@@ -289,29 +289,29 @@ Section Stack_refinement. ...@@ -289,29 +289,29 @@ Section Stack_refinement.
{ iNext. iExists _, _, _. by iFrame "Hh Hstk' Hstk Hl". } { iNext. iExists _, _, _. by iFrame "Hh Hstk' Hstk Hl". }
simpl. simpl.
iApply wp_pure_step_later; simpl; rewrite ?to_of_val; trivial. iApply wp_pure_step_later; simpl; rewrite ?to_of_val; trivial.
rewrite FG_iter_subst CG_iter_subst. iAsimpl. iAsimpl.
iModIntro. iNext. iModIntro. iNext.
iApply (wp_bind (fill [AppRCtx _; AppRCtx (RecV _)])); iApply (wp_bind (fill [AppRCtx _; SeqCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (w') "Hw"; iExact "Hw"|]. iApply wp_wand_l; iSplitR; [iIntros (w') "Hw"; iExact "Hw"|].
iApply wp_pure_step_later; simpl; rewrite ?to_of_val; trivial. iNext. iApply wp_pure_step_later; simpl; rewrite ?to_of_val; trivial. iNext.
iApply wp_value. iApply wp_value.
iApply (wp_bind (fill [AppRCtx (RecV _)])); iApply (wp_bind (fill [SeqCtx _]));
iApply wp_wand_l; iSplitR; [iIntros (w') "Hw"; iExact "Hw"|]. iApply wp_wand_l; iSplitR; [iIntros (w') "Hw"; iExact "Hw"|].
rewrite StackLink_unfold. rewrite StackLink_unfold.
iDestruct "HLK''" as (istk6 w') "[% HLK]"; simplify_eq/=. iDestruct "HLK''" as (istk6 w') "[% HLK]"; simplify_eq/=.
iSpecialize ("Hfs" $! (yn1, zn1) with "Hrel"). iSpecialize ("Hfs" $! (yn1, zn1) with "Hrel").
iSpecialize ("Hfs" $! _ (AppRCtx (RecV _) :: K)). iSpecialize ("Hfs" $! _ (SeqCtx _ :: K)).
iApply wp_wand_l; iSplitR "Hj"; [|iApply "Hfs"; by iFrame "#"]. iApply wp_wand_l; iSplitR "Hj"; [|iApply "Hfs"; by iFrame "#"].
iIntros (u) "/="; iDestruct 1 as (z) "[Hj [% %]]". iIntros (u) "/="; iDestruct 1 as (z) "[Hj [% %]]".
simpl. subst. iAsimpl. simpl. subst. iAsimpl.
iMod (step_rec with "[$Hspec $Hj]") as "Hj"; [done..|]. iMod (do_step_pure with "[$Hspec $Hj]") as "Hj"; [done..|].
iAsimpl. rewrite CG_iter_subst. iAsimpl. iAsimpl.
replace (CG_iter (of_val f2)) with (of_val (CG_iterV (of_val f2))) replace (CG_iter (of_val f2)) with (of_val (CG_iterV (of_val f2)))
by (by rewrite CG_iter_of_val). by (by rewrite CG_iter_of_val).
iMod (step_snd _ _ _ (AppRCtx _ :: K) with "[$Hspec Hj]") as "Hj"; iMod (step_snd _ _ _ (AppRCtx _ :: K) with "[$Hspec Hj]") as "Hj";
[| | |simpl; by iFrame "Hj"|]; rewrite ?to_of_val; auto. [| | |simpl; by iFrame "Hj"|]; rewrite ?to_of_val; auto.
iApply wp_pure_step_later; trivial. iApply wp_pure_step_later; trivial.
iNext. simpl. rewrite FG_iter_subst. iAsimpl. iNext. simpl.
replace (FG_iter (of_val f1)) with (of_val (FG_iterV (of_val f1))) replace (FG_iter (of_val f1)) with (of_val (FG_iterV (of_val f1)))
by (by rewrite FG_iter_of_val). by (by rewrite FG_iter_of_val).
iApply (wp_bind (fill [AppRCtx _])); iApply (wp_bind (fill [AppRCtx _]));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment