From ada45ac577711a072782d7e3900893a3ac71963c Mon Sep 17 00:00:00 2001 From: Robbert Krebbers <mail@robbertkrebbers.nl> Date: Sun, 30 Jun 2019 20:32:52 +0200 Subject: [PATCH] Generalize `list_sort_elem` specs have arbitrary tail. --- theories/channel/proto_channel.v | 6 +- theories/examples/list_sort_elem.v | 118 ++++++++++++++--------------- 2 files changed, 59 insertions(+), 65 deletions(-) diff --git a/theories/channel/proto_channel.v b/theories/channel/proto_channel.v index b2e01fa..ab8ca5d 100644 --- a/theories/channel/proto_channel.v +++ b/theories/channel/proto_channel.v @@ -390,7 +390,7 @@ Section proto. Global Instance proto_normalize_end d d' p pas q : ProtoNormalize d p pas q → - ProtoNormalize d' END ((d,p) :: pas) q | 1. + ProtoNormalize d' END ((d,p) :: pas) q | 0. Proof. rewrite /ProtoNormalize=> -> /=. destruct d'; by rewrite /= ?iProto_dual_end left_id. @@ -398,12 +398,12 @@ Section proto. Global Instance proto_normalize_app_r d p1 p2 pas q : ProtoNormalize d p2 pas q → - ProtoNormalize false p1 ((d,p2) :: pas) (p1 <++> q) | 10. + ProtoNormalize false p1 ((d,p2) :: pas) (p1 <++> q) | 0. Proof. by rewrite /ProtoNormalize=> -> /=. Qed. Global Instance proto_normalize_app_r_dual d p1 p2 pas q : ProtoNormalize d p2 pas q → - ProtoNormalize true p1 ((d,p2) :: pas) (iProto_dual p1 <++> q) | 10. + ProtoNormalize true p1 ((d,p2) :: pas) (iProto_dual p1 <++> q) | 0. Proof. by rewrite /ProtoNormalize=> -> /=. Qed. Global Instance proto_cont_normalize_O d v P p q pas : diff --git a/theories/examples/list_sort_elem.v b/theories/examples/list_sort_elem.v index c342dc9..0e216e1 100644 --- a/theories/examples/list_sort_elem.v +++ b/theories/examples/list_sort_elem.v @@ -47,11 +47,9 @@ Definition list_sort_elem_service : val := let: "x" := (if: recv "c1" then recv "c1" else assert #false) in list_sort_elem_service_merge "cmp" "c" "x" "c1" "c2". -Definition list_sort_elem_service_top : val := - λ: "c", - let: "cmp" := recv "c" in - list_sort_elem_service "cmp" "c". - +Definition list_sort_elem_service_top : val := λ: "c", + let: "cmp" := recv "c" in + list_sort_elem_service "cmp" "c". Section list_sort_elem. Context `{!heapG Σ, !proto_chanG Σ} (N : namespace). @@ -82,25 +80,25 @@ Section list_sort_elem. Definition head_protocol : list (A * val) → iProto Σ := fixpoint head_protocol_aux. Global Instance head_protocol_unfold xs : - ProtoUnfold (head_protocol xs) (head_protocol_aux head_protocol xs). + ProtoUnfold (head_protocol xs) (head_protocol_aux head_protocol xs) | 100. Proof. apply proto_unfold_eq, (fixpoint_unfold head_protocol_aux). Qed. Definition list_sort_elem_protocol : iProto Σ := head_protocol []. - - Lemma list_sort_elem_service_split_spec c c1 c2 xs xs1 xs2 : + + Lemma list_sort_elem_service_split_spec c p c1 c2 xs xs1 xs2 : {{{ - c ↣ iProto_dual (head_protocol xs) @ N ∗ + c ↣ iProto_dual (head_protocol xs) <++> p @ N ∗ c1 ↣ head_protocol xs1 @ N ∗ c2 ↣ head_protocol xs2 @ N }}} list_sort_elem_service_split c c1 c2 {{{ xs' xs1' xs2', RET #(); ⌜xs' ≡ₚ xs1' ++ xs2'⌠∗ - c ↣ iProto_dual (tail_protocol (xs ++ xs') []) @ N ∗ - c1 ↣ tail_protocol (xs1 ++ xs1') [] @ N ∗ c2 ↣ tail_protocol (xs2 ++ xs2') [] @ N + c ↣ iProto_dual (tail_protocol (xs ++ xs') []) <++> p @ N ∗ + c1 ↣ tail_protocol (xs1 ++ xs1') [] @ N ∗ c2 ↣ tail_protocol (xs2 ++ xs2') [] @ N }}}. Proof. iIntros (Ψ) "(Hc & Hc1 & Hc2) HΨ". iLöb as "IH" forall (c c1 c2 xs xs1 xs2 Ψ). - wp_rec. wp_branch; wp_pures. + wp_rec. wp_branch. - wp_recv (x v) as "HI". wp_select. wp_send with "[$HI]". wp_apply ("IH" with "Hc Hc2 Hc1"). iIntros (xs' xs1' xs2'); iDestruct 1 as (Hxs') "(Hc & Hc2 & Hc1)". @@ -110,17 +108,17 @@ Section list_sort_elem. iApply ("HΨ" $! [] [] []). rewrite !right_id_L. by iFrame. Qed. - Lemma list_sort_elem_service_move_spec c cin xs ys zs xs' ys' : + Lemma list_sort_elem_service_move_spec c p cin xs ys zs xs' ys' : xs ≡ₚ xs' ++ zs → ys ≡ₚ ys' ++ zs → Sorted R (fst <$> ys) → (∀ x, TlRel R x (fst <$> ys') → TlRel R x (fst <$> ys)) → {{{ - c ↣ iProto_dual (tail_protocol xs ys) @ N ∗ + c ↣ iProto_dual (tail_protocol xs ys) <++> p @ N ∗ cin ↣ tail_protocol xs' ys' @ N }}} list_sort_elem_service_move c cin - {{{ RET #(); c ↣ END @ N ∗ cin ↣ END @ N }}}. + {{{ RET #(); c ↣ p @ N ∗ cin ↣ END @ N }}}. Proof. iIntros (Hxs Hys Hsorted Hrel Ψ) "[Hc Hcin] HΨ". iLöb as "IH" forall (c cin xs ys xs' ys' Hxs Hys Hsorted Hrel). @@ -128,17 +126,17 @@ Section list_sort_elem. - wp_recv (x v) as (Htl) "HI". wp_select. wp_send with "[$HI]"; first by auto. wp_apply ("IH" with "[%] [%] [%] [%] Hc Hcin HΨ"). - { done. } - { by rewrite Hys -!assoc_L (comm _ zs). } - { rewrite fmap_app /=. apply Sorted_snoc; auto. } - { intros x'. rewrite !fmap_app. - inversion 1; discriminate_list || simplify_list_eq. by constructor. } + * done. + * by rewrite Hys -!assoc_L (comm _ zs). + * rewrite fmap_app /=. apply Sorted_snoc; auto. + * intros x'. rewrite !fmap_app. + inversion 1; discriminate_list || simplify_list_eq. by constructor. - iDestruct "Hys'" as %Hys'. wp_select with "[]". { by rewrite /= Hys Hxs Hys'. } iApply "HΨ". iFrame. Qed. - Lemma list_sort_elem_service_merge_spec cmp c c1 c2 xs ys xs1 xs2 y1 w1 ys1 ys2 : + Lemma list_sort_elem_service_merge_spec cmp c p c1 c2 xs ys xs1 xs2 y1 w1 ys1 ys2 : xs ≡ₚ xs1 ++ xs2 → ys ≡ₚ ys1 ++ ys2 → Sorted R (fst <$> ys) → @@ -146,12 +144,12 @@ Section list_sort_elem. (∀ x, TlRel R x (fst <$> ys2) → R x y1 → TlRel R x (fst <$> ys)) → cmp_spec I R cmp -∗ {{{ - c ↣ iProto_dual (tail_protocol xs ys) @ N ∗ + c ↣ iProto_dual (tail_protocol xs ys) <++> p @ N ∗ c1 ↣ tail_protocol xs1 (ys1 ++ [(y1,w1)]) @ N ∗ c2 ↣ tail_protocol xs2 ys2 @ N ∗ I y1 w1 }}} list_sort_elem_service_merge cmp c w1 c1 c2 - {{{ RET #(); c ↣ END @ N ∗ c1 ↣ END @ N ∗ c2 ↣ END @ N }}}. + {{{ RET #(); c ↣ p @ N }}}. Proof. iIntros (Hxs Hys Hsort Htl Htl_le) "#Hcmp !>". iIntros (Ψ) "(Hc & Hc1 & Hc2 & HIy1) HΨ". @@ -161,49 +159,48 @@ Section list_sort_elem. wp_pures. wp_apply ("Hcmp" with "[$HIy1 $HIx]"); iIntros "[HIy1 HIx]". case_bool_decide. + wp_select. wp_send with "[$HIy1 //]". - wp_apply ("IH" with "[%] [%] [%] [%] [%] Hc Hc2 Hc1 HIx"). - { by rewrite comm. } - { by rewrite assoc (comm _ ys2) Hys. } - { rewrite fmap_app. by apply Sorted_snoc. } - { rewrite fmap_app. by constructor. } - { intros x'. rewrite !fmap_app. - inversion 1; discriminate_list || simplify_list_eq. by constructor. } - iIntros "(?&?&?)". iApply "HΨ"; iFrame. + wp_apply ("IH" with "[%] [%] [%] [%] [%] Hc Hc2 Hc1 HIx HΨ"). + * by rewrite comm. + * by rewrite assoc (comm _ ys2) Hys. + * rewrite fmap_app. by apply Sorted_snoc. + * rewrite fmap_app. by constructor. + * intros x'. rewrite !fmap_app. + inversion 1; discriminate_list || simplify_list_eq. by constructor. + wp_select. wp_send with "[$HIx]". { iPureIntro. by apply Htl_le, total_not. } wp_apply ("IH" with "[% //] [%] [%] [%] [%] Hc Hc1 Hc2 HIy1 HΨ"). - { by rewrite Hys assoc. } - { rewrite fmap_app. by apply Sorted_snoc, Htl_le, total_not. } - { rewrite fmap_app. constructor. by apply total_not. } - { intros x'. rewrite !fmap_app. - inversion 1; discriminate_list || simplify_list_eq. by constructor. } + * by rewrite Hys assoc. + * rewrite fmap_app. by apply Sorted_snoc, Htl_le, total_not. + * rewrite fmap_app. constructor. by apply total_not. + * intros x'. rewrite !fmap_app. + inversion 1; discriminate_list || simplify_list_eq. by constructor. - iDestruct "Hys2" as %Hys2. wp_select. wp_send with "[$HIy1 //]". wp_apply (list_sort_elem_service_move_spec with "[$Hc $Hc1]"). - { done. } - { by rewrite Hys Hys2 -!assoc_L (comm _ xs2). } - { rewrite fmap_app. by apply Sorted_snoc. } - { intros x'. rewrite !fmap_app. - inversion 1; discriminate_list || simplify_list_eq. by constructor. } - iIntros "[Hc Hc1]". iApply "HΨ". iFrame. + * done. + * by rewrite Hys Hys2 -!assoc_L (comm _ xs2). + * rewrite fmap_app. by apply Sorted_snoc. + * intros x'. rewrite !fmap_app. + inversion 1; discriminate_list || simplify_list_eq. by constructor. + * iIntros "[Hc Hc1]". iApply "HΨ". iFrame. Qed. - Lemma list_sort_elem_service_spec cmp c : + Lemma list_sort_elem_service_spec cmp c p : cmp_spec I R cmp -∗ - {{{ c ↣ iProto_dual list_sort_elem_protocol @ N }}} + {{{ c ↣ iProto_dual list_sort_elem_protocol <++> p @ N }}} list_sort_elem_service cmp c - {{{ RET #(); c ↣ END @ N }}}. + {{{ RET #(); c ↣ p @ N }}}. Proof. - iIntros "#Hcmp !>" (Ψ) "Hc HΨ". iLöb as "IH" forall (c Ψ). + iIntros "#Hcmp !>" (Ψ) "Hc HΨ". iLöb as "IH" forall (c p Ψ). wp_rec; wp_pures. wp_branch; wp_pures. - wp_recv (x1 v1) as "HIx1". wp_branch; wp_pures. + wp_recv (x2 v2) as "HIx2". - wp_apply (start_chan_proto_spec N list_sort_elem_protocol). - { iIntros (cy) "Hcy". wp_apply ("IH" with "Hcy"); auto. } + wp_apply (start_chan_proto_spec N (list_sort_elem_protocol <++> END)%proto). + { iIntros (cy) "Hcy". wp_apply ("IH" with "Hcy"). auto. } iIntros (cy) "Hcy". - wp_apply (start_chan_proto_spec N list_sort_elem_protocol). + wp_apply (start_chan_proto_spec N (list_sort_elem_protocol <++> END)%proto). { iIntros (cz) "Hcz". wp_apply ("IH" with "Hcz"); auto. } - iIntros (cz) "Hcz". + iIntros (cz) "Hcz". rewrite !right_id. wp_select. wp_send with "[$HIx1]". wp_select. wp_send with "[$HIx2]". wp_apply (list_sort_elem_service_split_spec with "[$Hc $Hcy $Hcz]"). @@ -211,13 +208,12 @@ Section list_sort_elem. wp_branch as "_" "Hnil"; last first. { by iDestruct "Hnil" as %?%Permutation_nil_cons. } wp_recv (x v) as "[_ HIx]". - wp_apply (list_sort_elem_service_merge_spec _ _ _ _ _ [] _ _ _ _ [] [] + wp_apply (list_sort_elem_service_merge_spec _ _ _ _ _ _ [] _ _ _ _ [] [] with "Hcmp [$Hc $Hcy $Hcz $HIx]"); simpl; auto using TlRel_nil, Sorted_nil. - { by rewrite Hxs' Permutation_middle. } - iIntros "(Hc & Hcy & Hcz)". by iApply "HΨ". + by rewrite Hxs' Permutation_middle. + wp_select. wp_send with "[$HIx1]"; first by auto using TlRel_nil. - by wp_apply (select_spec with "[$Hc]"). - - by wp_apply (select_spec with "[$Hc]"). + wp_select. by iApply "HΨ". + - wp_select. by iApply "HΨ". Qed. End list_sort_elem_inner. @@ -227,15 +223,13 @@ Section list_sort_elem. MSG cmp {{ cmp_spec I R cmp }}; head_protocol I R [])%proto. - Lemma list_sort_elem_service_top_spec c : - {{{ c ↣ iProto_dual list_sort_elem_top_protocol @ N }}} + Lemma list_sort_elem_service_top_spec c p : + {{{ c ↣ iProto_dual list_sort_elem_top_protocol <++> p @ N }}} list_sort_elem_service_top c - {{{ RET #(); c ↣ END @ N }}}. + {{{ RET #(); c ↣ p @ N }}}. Proof. - iIntros (Ψ) "Hc HΨ". - wp_lam. + iIntros (Ψ) "Hc HΨ". wp_lam. wp_recv (? I R ? ? cmp) as "#Hcmp". - wp_apply (list_sort_elem_service_spec with "Hcmp Hc")=> //. + by wp_apply (list_sort_elem_service_spec with "Hcmp Hc"). Qed. - End list_sort_elem. -- GitLab