Commit 70e0bae2 authored by Robbert Krebbers's avatar Robbert Krebbers

Kill bigops.

parent 4ae19de7
......@@ -67,8 +67,8 @@ Section channel.
Definition chan_inv (γ : chan_name) (l r : loc) : iProp Σ :=
( ls rs,
llist l ls own (chan_l_name γ) ( to_auth_excl ls)
llist r rs own (chan_r_name γ) ( to_auth_excl rs))%I.
llist sbi_internal_eq l ls own (chan_l_name γ) ( to_auth_excl ls)
llist sbi_internal_eq r rs own (chan_r_name γ) ( to_auth_excl rs))%I.
Typeclasses Opaque chan_inv.
Definition is_chan (γ : chan_name) (c1 c2 : val) : iProp Σ :=
......@@ -99,8 +99,8 @@ Section channel.
iMod (own_alloc ( (to_auth_excl []) (to_auth_excl []))) as (rsγ) "[Hrs Hrs']".
{ by apply auth_both_valid. }
wp_apply (newlock_spec N ( ls rs,
llist l ls own lsγ ( to_auth_excl ls)
llist r rs own rsγ ( to_auth_excl rs))%I with "[Hl Hr Hls Hrs]").
llist sbi_internal_eq l ls own lsγ ( to_auth_excl ls)
llist sbi_internal_eq r rs own rsγ ( to_auth_excl rs))%I with "[Hl Hr Hls Hrs]").
{ eauto 10 with iFrame. }
iIntros (lk γlk) "#Hlk". wp_pures.
iApply ("HΦ" $! _ _ (Chan_name γlk lsγ rsγ)); simpl.
......@@ -109,9 +109,9 @@ Section channel.
Lemma chan_inv_alt s γ l r :
chan_inv γ l r ls rs,
llist (side_elim s l r) ls
llist sbi_internal_eq (side_elim s l r) ls
own (side_elim s chan_l_name chan_r_name γ) ( to_auth_excl ls)
llist (side_elim s r l) rs
llist sbi_internal_eq (side_elim s r l) rs
own (side_elim s chan_r_name chan_l_name γ) ( to_auth_excl rs).
Proof.
destruct s; rewrite /chan_inv //=.
......@@ -137,7 +137,7 @@ Section channel.
iDestruct (excl_eq with "Hvs Hchan") as %<-%leibniz_equiv.
iMod (excl_update _ _ _ (vs ++ [v]) with "Hvs Hchan") as "[Hvs Hchan]".
wp_pures. iMod ("HΦ" with "Hchan") as "HΦ"; iModIntro.
wp_apply (lsnoc_spec with "Hll"); iIntros "Hll".
wp_apply (lsnoc_spec with "[$Hll //]"); iIntros "Hll".
wp_apply (release_spec with "[-HΦ $Hlock $Hlocked]"); last eauto.
iApply (chan_inv_alt s).
rewrite /llist. eauto 20 with iFrame.
......@@ -171,7 +171,7 @@ Section channel.
iMod (excl_update _ _ _ vs with "Hvs Hvs'") as "[Hvs Hvs']".
wp_pures. iMod ("HΦ" with "[//] Hvs'") as "HΦ"; iModIntro.
wp_apply (lisnil_spec with "Hll"); iIntros "Hll".
wp_apply (lpop_spec with "Hll"); iIntros "Hll".
wp_apply (lpop_spec with "Hll"); iIntros (v') "[% Hll]"; simplify_eq/=.
wp_apply (release_spec with "[-HΦ $Hlocked $Hlock]").
{ iApply (chan_inv_alt s).
rewrite /llist. eauto 10 with iFrame. }
......
......@@ -63,9 +63,7 @@ Section map.
Implicit Types n : nat.
Definition map_spec (vmap : val) : iProp Σ := ( x v,
{{{ IA x v }}}
vmap v
{{{ l ws, RET #l; llist l ws [ list] y;w map x;ws, IB y w }}})%I.
{{{ IA x v }}} vmap v {{{ l, RET #l; llist IB l (map x) }}})%I.
Definition map_worker_protocol_aux (rec : nat -d> gmultiset A -d> iProto Σ) :
nat -d> gmultiset A -d> iProto Σ := λ i X,
......@@ -75,7 +73,7 @@ Section map.
<+>
rec (pred i) X
) <{ i 1 X = }&>
<?> x (l : loc) ws, MSG #l {{ x X llist l ws [ list] y;w map x;ws, IB y w }};
<?> x (l : loc), MSG #l {{ x X llist IB l (map x) }};
rec i (X {[ x ]}))%proto.
Instance map_worker_protocol_aux_contractive : Contractive map_worker_protocol_aux.
Proof. solve_proper_prepare. f_equiv. solve_proto_contractive. Qed.
......@@ -112,7 +110,7 @@ Section map.
rewrite left_id_L.
wp_apply (release_spec with "[$Hlk $Hl Hc Hs]").
{ iExists (S i), _. iFrame. }
clear dependent i X. iIntros "Hu". wp_apply ("Hmap" with "HI"); iIntros (l ws) "HI".
clear dependent i X. iIntros "Hu". wp_apply ("Hmap" with "HI"); iIntros (l) "HI".
wp_apply (acquire_spec with "[$Hlk $Hu]"); iIntros "[Hl H]".
iDestruct "H" as (i X) "[Hs Hc]".
iDestruct (@server_agree with "Hs Hγ")
......@@ -159,41 +157,31 @@ Section map.
wp_apply (start_map_workers_spec with "Hf [$Hlk $Hγs]"); auto.
Qed.
Lemma par_map_server_spec n c l k vs xs ws X ys :
Lemma par_map_server_spec n c l k xs X ys :
(n = 0 X = xs = [])
{{{
llist l vs llist k ws
c map_worker_protocol n X @ N
([ list] x;v xs;vs, IA x v) ([ list] y;w ys;ws, IB y w)
}}}
{{{ llist IA l xs llist IB k ys c map_worker_protocol n X @ N }}}
par_map_server #n c #l #k
{{{ ys' ws', RET #();
ys' (xs ++ elements X) = map
llist k ws' [ list] y;w ys' ++ ys;ws', IB y w
}}}.
{{{ ys', RET #(); ys' (xs ++ elements X) = map llist IB k (ys' ++ ys) }}}.
Proof.
iIntros (Hn Φ) "(Hl & Hk & Hc & HIA & HIB) HΦ".
iLöb as "IH" forall (n l vs xs ws X ys Hn Φ); wp_rec; wp_pures; simpl.
iIntros (Hn Φ) "(Hl & Hk & Hc) HΦ".
iLöb as "IH" forall (n l xs X ys Hn Φ); wp_rec; wp_pures; simpl.
case_bool_decide; wp_pures; simplify_eq/=.
{ destruct Hn as [-> ->]; first lia.
iApply ("HΦ" $! []); simpl; auto with iFrame. }
destruct n as [|n]=> //=. wp_branch as %?|%_; wp_pures.
- wp_apply (lisnil_spec with "Hl"); iIntros "Hl".
destruct vs as [|v vs], xs as [|x xs]; csimpl; try done; wp_pures.
destruct xs as [|x xs]; csimpl; wp_pures.
+ wp_select. wp_pures. rewrite Nat2Z.inj_succ Z.sub_1_r Z.pred_succ.
iApply ("IH" with "[%] Hl Hk Hc [//] [$] HΦ"); naive_solver.
+ iDestruct "HIA" as "[HIAx HIA]". wp_select.
wp_apply (lpop_spec with "Hl"); iIntros "Hl".
wp_send with "[$HIAx]".
wp_apply ("IH" with "[] Hl Hk Hc HIA HIB"); first done.
iIntros (ys' ws').
iApply ("IH" with "[%] Hl Hk Hc [$]"); naive_solver.
+ wp_select. wp_apply (lpop_spec with "Hl"); iIntros (v) "[HIx Hl]".
wp_send with "[$HIx]".
wp_apply ("IH" with "[] Hl Hk Hc"); first done. iIntros (ys').
rewrite gmultiset_elements_disj_union gmultiset_elements_singleton.
rewrite assoc_L -(comm _ [x]). iApply "HΦ".
- wp_recv (x l' w) as (Hx) "[Hl' HIBx]".
- wp_recv (x l') as (Hx) "Hl'".
wp_apply (lprep_spec with "[$Hk $Hl']"); iIntros "[Hk _]".
wp_apply ("IH" $! _ _ _ _ _ _ (_ ++ _) with "[] Hl Hk Hc HIA [HIBx HIB]"); first done.
{ simpl; iFrame. }
iIntros (ys' ws'); iDestruct 1 as (Hys) "HIB"; simplify_eq/=.
wp_apply ("IH" with "[] Hl Hk Hc"); first done.
iIntros (ys'); iDestruct 1 as (Hys) "Hk"; simplify_eq/=.
iApply ("HΦ" $! (ys' ++ map x)). iSplit.
+ iPureIntro. rewrite (gmultiset_disj_union_difference {[ x ]} X)
-?gmultiset_elem_of_singleton_subseteq //.
......@@ -202,18 +190,18 @@ Section map.
+ by rewrite -assoc_L.
Qed.
Lemma par_map_spec n vmap l vs xs :
Lemma par_map_spec n vmap l xs :
0 < n
map_spec vmap -
{{{ llist l vs [ list] x;v xs;vs, IA x v }}}
{{{ llist IA l xs }}}
par_map #n vmap #l
{{{ k ys ws, RET #k; ys xs = map llist k ws [ list] y;w ys;ws, IB y w }}}.
{{{ k ys, RET #k; ys xs = map llist IB k ys }}}.
Proof.
iIntros (?) "#Hmap !>"; iIntros (Φ) "[Hl HI] HΦ". wp_lam; wp_pures.
iIntros (?) "#Hmap !>"; iIntros (Φ) "Hl HΦ". wp_lam; wp_pures.
wp_apply (start_map_service_spec with "Hmap [//]"); iIntros (c) "Hc".
wp_pures. wp_apply (lnil_spec with "[//]"); iIntros (k) "Hk".
wp_apply (par_map_server_spec _ _ _ _ _ _ [] [] with "[$Hl $Hk $Hc $HI //]"); first lia.
iIntros (ys ws) "H". rewrite /= gmultiset_elements_empty !right_id_L .
wp_pures. by iApply "HΦ".
wp_apply (par_map_server_spec with "[$Hl $Hk $Hc //]"); first lia.
iIntros (ys) "[??]". rewrite /= gmultiset_elements_empty !right_id_L .
wp_pures. iApply "HΦ"; auto.
Qed.
End map.
This diff is collapsed.
......@@ -34,47 +34,42 @@ Section sort.
(<!> A (I : A val iProp Σ) (R : A A Prop)
`{!RelDecision R, !Total R} (cmp : val),
MSG cmp {{ cmp_spec I R cmp }};
<!> (xs : list A) (l : loc) (vs : list val),
MSG #l {{ llist l vs [ list] x;v xs;vs, I x v }};
<?> (xs' : list A) (vs' : list val),
MSG #() {{ Sorted R xs' xs' xs
llist l vs' [ list] x;v xs';vs', I x v }};
<!> (xs : list A) (l : loc), MSG #l {{ llist I l xs }};
<?> (xs' : list A), MSG #() {{ Sorted R xs' xs' xs llist I l xs' }};
END)%proto.
Lemma lmerge_spec {A} (I : A val iProp Σ) (R : A A Prop)
`{!RelDecision R, !Total R} (cmp : val) l1 l2 xs1 xs2 vs1 vs2 :
`{!RelDecision R, !Total R} (cmp : val) l1 l2 xs1 xs2 :
cmp_spec I R cmp -
{{{
llist l1 vs1 llist l2 vs2
([ list] x;v xs1;vs1, I x v) ([ list] x;v xs2;vs2, I x v)
}}}
{{{ llist I l1 xs1 llist I l2 xs2 }}}
lmerge cmp #l1 #l2
{{{ ws, RET #(); llist l1 ws [ list] x;v list_merge R xs1 xs2;ws, I x v }}}.
{{{ RET #(); llist I l1 (list_merge R xs1 xs2) }}}.
Proof.
iIntros "#Hcmp" (Ψ) "!> (Hl1 & Hl2 & HI1 & HI2) HΨ".
iLöb as "IH" forall (l2 xs1 xs2 vs1 vs2 Ψ).
iIntros "#Hcmp" (Ψ) "!> [Hl1 Hl2] HΨ".
iLöb as "IH" forall (l2 xs1 xs2 Ψ).
wp_lam. wp_apply (lisnil_spec with "Hl1"); iIntros "Hl1".
destruct xs1 as [|x1 xs1], vs1 as [|v1 vs1]; simpl; done || wp_pures.
destruct xs1 as [|x1 xs1]; wp_pures.
{ wp_apply (lapp_spec with "[$Hl1 $Hl2]"); iIntros "[Hl1 _] /=".
iApply "HΨ". iFrame. by rewrite list_merge_nil_l. }
wp_apply (lisnil_spec with "Hl2"); iIntros "Hl2".
destruct xs2 as [|x2 xs2], vs2 as [|v2 vs2]; simpl; done || wp_pures.
destruct xs2 as [|x2 xs2]; wp_pures.
{ iApply "HΨ". iFrame. }
wp_apply (lhead_spec with "Hl1"); iIntros "Hl1".
wp_apply (lhead_spec with "Hl2"); iIntros "Hl2".
iDestruct "HI1" as "[HI1 HI1']"; iDestruct "HI2" as "[HI2 HI2']".
wp_apply ("Hcmp" with "[$HI1 $HI2]"); iIntros "[HI1 HI2]".
wp_apply (lhead_spec_aux with "Hl1"); iIntros (v1 l1') "[HIx1 Hl1]".
wp_apply (lhead_spec_aux with "Hl2"); iIntros (v2 l2') "[HIx2 Hl2]".
wp_apply ("Hcmp" with "[$HIx1 $HIx2]"); iIntros "[HIx1 HIx2] /=".
case_bool_decide; wp_pures.
- rewrite decide_True //.
wp_apply (lpop_spec with "Hl1"); iIntros "Hl1".
wp_apply ("IH" $! _ _ (x2 :: _) with "Hl1 Hl2 HI1' [$HI2 $HI2']").
iIntros (ws) "[Hl1 HI]".
wp_apply (lcons_spec with "Hl1"); iIntros "Hl1". iApply "HΨ". iFrame.
wp_apply (lpop_spec_aux with "Hl1"); iIntros "Hl1".
wp_apply ("IH" $! _ _ (_ :: _) with "Hl1 [HIx2 Hl2]").
{ iExists _, _. iFrame. }
iIntros "Hl1".
wp_apply (lcons_spec with "[$Hl1 $HIx1]"). iIntros "Hl1". iApply "HΨ". iFrame.
- rewrite decide_False //.
wp_apply (lpop_spec with "Hl2"); iIntros "Hl2".
wp_apply ("IH" $! _ (x1 :: _) with "Hl1 Hl2 [$HI1 $HI1'] HI2'").
iIntros (ws) "[Hl1 HI]".
wp_apply (lcons_spec with "Hl1"); iIntros "Hl1". iApply "HΨ". iFrame.
wp_apply (lpop_spec_aux with "Hl2"); iIntros "Hl2".
wp_apply ("IH" $! _ (_ :: _) with "[HIx1 Hl1] Hl2").
{ iExists _, _. iFrame. }
iIntros "Hl1".
wp_apply (lcons_spec with "[$Hl1 $HIx2]"); iIntros "Hl1". iApply "HΨ". iFrame.
Qed.
Lemma sort_service_spec p c :
......@@ -84,16 +79,14 @@ Section sort.
Proof.
iIntros (Ψ) "Hc HΨ". iLöb as "IH" forall (p c Ψ). wp_lam.
wp_recv (A I R ?? cmp) as "#Hcmp".
wp_recv (xs l vs) as "[Hl HI]".
wp_recv (xs l) as "Hl".
wp_apply (llength_spec with "Hl"); iIntros "Hl".
iDestruct (big_sepL2_length with "HI") as %<-.
wp_op; case_bool_decide as Hlen; wp_if.
{ assert (Sorted R xs).
{ destruct xs as [|x1 [|x2 xs]]; simpl in *; eauto with lia. }
wp_send with "[$Hl $HI]"; first by auto. by iApply "HΨ". }
wp_send with "[$Hl]"; first by auto. by iApply "HΨ". }
wp_apply (lsplit_spec with "Hl"); iIntros (l2 vs1 vs2);
iDestruct 1 as (->) "[Hl1 Hl2]".
iDestruct (big_sepL2_app_inv_r with "HI") as (xs1 xs2 ->) "[HI1 HI2]".
wp_apply (start_chan_proto_spec N sort_protocol); iIntros (cy) "Hcy".
{ rewrite -{2}(right_id END%proto _ (iProto_dual _)).
wp_apply ("IH" with "Hcy"); auto. }
......@@ -101,13 +94,13 @@ Section sort.
{ rewrite -{2}(right_id END%proto _ (iProto_dual _)).
wp_apply ("IH" with "Hcz"); auto. }
wp_send with "[$Hcmp]".
wp_send with "[$Hl1 $HI1]".
wp_send with "[$Hl1]".
wp_send with "[$Hcmp]".
wp_send with "[$Hl2 $HI2]".
wp_recv (ys1 ws1) as (??) "[Hl1 HI1]".
wp_recv (ys2 ws2) as (??) "[Hl2 HI2]".
wp_apply (lmerge_spec with "Hcmp [$Hl1 $Hl2 $HI1 $HI2]"); iIntros (ws) "[Hl HI]".
wp_send ((list_merge R ys1 ys2) ws) with "[$Hl $HI]".
wp_send with "[$Hl2]".
wp_recv (ys1) as (??) "Hl1".
wp_recv (ys2) as (??) "Hl2".
wp_apply (lmerge_spec with "Hcmp [$Hl1 $Hl2]"); iIntros "Hl".
wp_send ((list_merge R ys1 ys2)) with "[$Hl]".
- iSplit; iPureIntro.
+ by apply (Sorted_list_merge _).
+ rewrite (merge_Permutation R). by f_equiv.
......
......@@ -12,12 +12,11 @@ Section sort_client.
Context `{!heapG Σ, !proto_chanG Σ} (N : namespace).
Lemma sort_client_spec {A} (I : A val iProp Σ) R
`{!RelDecision R, !Total R} cmp l (vs : list val) (xs : list A) :
`{!RelDecision R, !Total R} cmp l (xs : list A) :
cmp_spec I R cmp -
{{{ llist l vs [ list] x;v xs;vs, I x v }}}
{{{ llist I l xs }}}
sort_client cmp #l
{{{ ys ws, RET #(); Sorted R ys ys xs
llist l ws [ list] y;w ys;ws, I y w }}}.
{{{ ys, RET #(); Sorted R ys ys xs llist I l ys }}}.
Proof.
iIntros "#Hcmp !>" (Φ) "Hl HΦ". wp_lam.
wp_apply (start_chan_proto_spec N sort_protocol); iIntros (c) "Hc".
......@@ -25,25 +24,7 @@ Section sort_client.
wp_apply (sort_service_spec with "Hc"); auto. }
wp_send with "[$Hcmp]".
wp_send with "[$Hl]".
wp_recv (ys ws) as "(Hsorted & Hperm & Hl & HI)".
wp_recv (ys) as "(Hsorted & Hperm & Hl)".
wp_pures. iApply "HΦ"; iFrame.
Qed.
Lemma sort_client_Zle_spec l (xs : list Z) :
{{{ llist l (LitV LitInt <$> xs) }}}
sort_client cmpZ #l
{{{ ys, RET #(); Sorted () ys ys xs llist l (LitV LitInt <$> ys) }}}.
Proof.
iIntros (Φ) "Hl HΦ".
iApply (sort_client_spec IZ () _ _ (LitV LitInt <$> xs) xs with "[] [Hl] [HΦ]").
{ iApply cmpZ_spec. }
{ iFrame "Hl". iInduction xs as [|x xs] "IH"; csimpl; by iFrame "#". }
iIntros "!>" (ys ws) "(?&?&?&HI)".
iAssert ws = (LitV LitInt) <$> ys %I with "[HI]" as %->.
{ iInduction ys as [|y ys] "IH" forall (ws);
destruct ws as [|w ws]; csimpl; try done.
iDestruct "HI" as "[-> HI2]".
by iDestruct ("IH" with "HI2") as %->. }
iApply ("HΦ" $! ys with "[$]").
Qed.
End sort_client.
......@@ -28,61 +28,56 @@ Section sort_elem_client.
Context `{!heapG Σ, !proto_chanG Σ} (N : namespace).
Context {A} (I : A val iProp Σ) (R : relation A) `{!RelDecision R, !Total R}.
Lemma send_all_spec c p xs' l xs vs :
{{{ llist l vs c sort_elem_head_protocol I R xs' <++> p @ N [ list] x;v xs;vs, I x v }}}
Lemma send_all_spec c p xs' l xs :
{{{ llist I l xs c sort_elem_head_protocol I R xs' <++> p @ N }}}
send_all c #l
{{{ RET #(); c sort_elem_head_protocol I R (xs' ++ xs) <++> p @ N }}}.
Proof.
iIntros (Φ) "(Hl & Hc & HI) HΦ".
iInduction xs as [|x xs] "IH" forall (xs' vs); destruct vs as [|v vs]=>//.
iIntros (Φ) "[Hl Hc] HΦ".
iInduction xs as [|x xs] "IH" forall (xs').
{ wp_lam. wp_apply (lisnil_spec with "Hl"); iIntros "Hl"; wp_pures.
iApply "HΦ". rewrite right_id_L. iFrame. }
iDestruct "HI" as "[HIxv HI]". wp_lam.
wp_apply (lisnil_spec with "Hl"); iIntros "Hl". wp_select.
wp_apply (lpop_spec with "Hl"); iIntros "Hl".
wp_send with "[$HIxv]". wp_apply ("IH" with "Hl Hc HI"). by rewrite -assoc_L.
wp_lam. wp_apply (lisnil_spec with "Hl"); iIntros "Hl". wp_select.
wp_apply (lpop_spec with "Hl"); iIntros (v) "[HIx Hl]".
wp_send with "[$HIx]". wp_apply ("IH" with "Hl Hc"). by rewrite -assoc_L.
Qed.
Lemma recv_all_spec c p xs ys' :
Sorted R ys'
{{{ c sort_elem_tail_protocol I R xs ys' <++> p @ N }}}
recv_all c
{{{ l ys ws, RET #l;
Sorted R (ys' ++ ys) ys' ++ ys xs
llist l ws c p @ N [ list] y;w ys;ws, I y w
{{{ l ys, RET #l;
Sorted R (ys' ++ ys) ys' ++ ys xs llist I l ys c p @ N
}}}.
Proof.
iIntros (Hsort Φ) "Hc HΦ".
iLöb as "IH" forall (xs ys' Φ Hsort).
wp_lam. wp_branch as %_ | %Hperm; wp_pures.
- wp_recv (y v) as (Htl) "HIxv".
- wp_recv (y v) as (Htl) "HIx".
wp_apply ("IH" with "[] Hc"); first by auto using Sorted_snoc.
iIntros (l ys ws). rewrite -!assoc_L. iDestruct 1 as (??) "(Hl & Hc & HI)".
wp_apply (lcons_spec with "Hl"); iIntros "Hl"; wp_pures.
iApply ("HΦ" $! _ (y :: ys)); simpl; eauto with iFrame.
iIntros (l ys). rewrite -!assoc_L. iDestruct 1 as (??) "[Hl Hc]".
wp_apply (lcons_spec with "[$Hl $HIx]"); iIntros "Hl"; wp_pures.
iApply ("HΦ" with "[$Hl $Hc]"); simpl; eauto.
- wp_apply (lnil_spec with "[//]"); iIntros (l) "Hl".
iApply ("HΦ" $! _ [] []); rewrite /= right_id_L; by iFrame.
iApply ("HΦ" $! _ []); rewrite /= right_id_L; by iFrame.
Qed.
Lemma sort_client_spec cmp l vs xs :
Lemma sort_client_spec cmp l xs :
cmp_spec I R cmp -
{{{ llist l vs [ list] x;v xs;vs, I x v }}}
{{{ llist I l xs }}}
sort_elem_client cmp #l
{{{ k ys ws, RET #k;
Sorted R ys ys xs
llist k ws [ list] y;w ys;ws, I y w
}}}.
{{{ k ys, RET #k; Sorted R ys ys xs llist I k ys }}}.
Proof.
iIntros "#Hcmp !>" (Φ) "[Hl HI] HΦ". wp_lam.
iIntros "#Hcmp !>" (Φ) "Hl HΦ". wp_lam.
wp_apply (start_chan_proto_spec N (sort_elem_top_protocol <++> END)%proto);
iIntros (c) "Hc".
{ wp_apply (sort_elem_service_top_spec N with "Hc"); auto. }
rewrite /sort_elem_top_protocol.
wp_send (A I R) with "[$Hcmp]".
wp_apply (send_all_spec with "[$Hl $HI $Hc]"); iIntros "Hc".
wp_apply (send_all_spec with "[$Hl $Hc]"); iIntros "Hc".
wp_select.
wp_apply (recv_all_spec _ _ _ [] with "[$Hc]"); auto.
iIntros (k ys ws) "/=". iDestruct 1 as (??) "(Hk & _ & HI)".
wp_apply (recv_all_spec with "Hc"); auto.
iIntros (k ys) "/=". iDestruct 1 as (??) "[Hk _]".
iApply "HΦ"; auto with iFrame.
Qed.
End sort_elem_client.
This diff is collapsed.
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