From a2b213bf2930bc1e5b45cdcae2f587c8aa12cfc3 Mon Sep 17 00:00:00 2001 From: Jacques-Henri Jourdan <jacques-henri.jourdan@normalesup.org> Date: Sat, 21 Jan 2017 09:12:23 +0100 Subject: [PATCH] Cell : cleanup a bit. Transform the various primitices into functions. --- theories/lifetime/na_borrow.v | 1 - theories/typing/unsafe/cell.v | 119 ++++++++++++++++++++++++++-------- 2 files changed, 92 insertions(+), 28 deletions(-) diff --git a/theories/lifetime/na_borrow.v b/theories/lifetime/na_borrow.v index b3f1168e..3e7940eb 100644 --- a/theories/lifetime/na_borrow.v +++ b/theories/lifetime/na_borrow.v @@ -55,7 +55,6 @@ Section na_bor. iIntros (?) "#LFT#H†". iApply (bor_na with ">"). done. by iApply (bor_fake with "LFT H†"). Qed. - End na_bor. Typeclasses Opaque na_bor. diff --git a/theories/typing/unsafe/cell.v b/theories/typing/unsafe/cell.v index 2020e193..65e9def8 100644 --- a/theories/typing/unsafe/cell.v +++ b/theories/typing/unsafe/cell.v @@ -13,39 +13,65 @@ Section cell. Program Definition cell (ty : type) := {| ty_size := ty.(ty_size); ty_own := ty.(ty_own); - ty_shr κ tid l := (&na{κ, tid, shrN.@l} l ↦∗: ty.(ty_own) tid)%I |}. + ty_shr κ tid l := + (∃ P, ▷ □ (P ↔ l ↦∗: ty.(ty_own) tid) ∗ &na{κ, tid, shrN.@l}P)%I |}. Next Obligation. apply ty_size_eq. Qed. Next Obligation. - iIntros (ty E κ l tid q ?) "#LFT Hown $". by iApply bor_na. + iIntros (ty E κ l tid q ?) "#LFT Hown $". iExists _. + iMod (bor_na with "Hown") as "$". set_solver. iIntros "!>!>!#". iSplit; auto. Qed. Next Obligation. - iIntros (ty ?? tid l) "#LFT". iApply na_bor_shorten. + iIntros (ty ?? tid l) "#LFT #H⊑ H". iDestruct "H" as (P) "[??]". + iExists _. iFrame. by iApply (na_bor_shorten with "H⊑"). Qed. - (* TODO: non-expansiveness, proper wrt. eqtype *) + Global Instance cell_ne n : Proper (dist n ==> dist n) cell. + Proof. + intros ?? EQ. split; [split|]; simpl; try apply EQ. + intros κ tid l. repeat (apply EQ || f_contractive || f_equiv). + Qed. + + Global Instance cell_mono E L : Proper (eqtype E L ==> subtype E L) cell. + Proof. + iIntros (?? EQ%eqtype_unfold) "#LFT #HE #HL". + iDestruct (EQ with "LFT HE HL") as "(% & #Hown & #Hshr)". + iSplit; [done|iSplit; iIntros "!# * H"]. + - iApply ("Hown" with "H"). + - iDestruct "H" as (P) "[#HP H]". iExists P. iFrame. iSplit; iNext; iIntros "!# H". + + iDestruct ("HP" with "H") as (vl) "[??]". iExists vl. iFrame. by iApply "Hown". + + iApply "HP". iDestruct "H" as (vl) "[??]". iExists vl. iFrame. by iApply "Hown". + Qed. + Lemma cell_mono' E L ty1 ty2 : eqtype E L ty1 ty2 → subtype E L (cell ty1) (cell ty2). + Proof. eapply cell_mono. Qed. + Global Instance cell_proper E L : Proper (eqtype E L ==> eqtype E L) cell. + Proof. by split; apply cell_mono. Qed. + Lemma cell_proper' E L ty1 ty2 : eqtype E L ty1 ty2 → eqtype E L (cell ty1) (cell ty2). + Proof. eapply cell_proper. Qed. Global Instance cell_copy : Copy ty → Copy (cell ty). Proof. intros ty Hcopy. split; first by intros; simpl; apply _. iIntros (κ tid E F l q ??) "#LFT #Hshr Htl Htok". iExists 1%Qp. simpl in *. + iDestruct "Hshr" as (P) "[HP Hshr]". (* Size 0 needs a special case as we can't keep the thread-local invariant open. *) destruct (ty_size ty) as [|sz] eqn:Hsz. { iMod (na_bor_acc with "LFT Hshr Htok Htl") as "(Hown & Htl & Hclose)"; [solve_ndisj..|]. - iDestruct "Hown" as (vl) "[H↦ #Hown]". + iDestruct ("HP" with "Hown") as (vl) "[H↦ #Hown]". simpl. assert (F ∖ ∅ = F) as -> by set_solver+. iDestruct (ty_size_eq with "Hown") as "#>%". rewrite ->Hsz in *. iMod ("Hclose" with "[H↦] Htl") as "[$ $]". - { iExists vl. by iFrame. } + { iApply "HP". iExists vl. by iFrame. } iModIntro. iSplitL "". { iNext. iExists vl. destruct vl; last done. iFrame "Hown". by iApply heap_mapsto_vec_nil. } by iIntros "$ _". } (* Now we are in the non-0 case. *) - iMod (na_bor_acc with "LFT Hshr Htok Htl") as "($ & Htl & Hclose)"; [solve_ndisj..|]. + iMod (na_bor_acc with "LFT Hshr Htok Htl") as "(H & Htl & Hclose)"; [solve_ndisj..|]. + iDestruct ("HP" with "H") as "$". iDestruct (na_own_acc with "Htl") as "($ & Hclose')"; first by set_solver. iIntros "!> Htl Hown". iPoseProof ("Hclose'" with "Htl") as "Htl". - iMod ("Hclose" with "Hown Htl") as "[$ $]". done. + iMod ("Hclose" with "[Hown] Htl") as "[$ $]"; last done. by iApply "HP". Qed. Global Instance cell_send : @@ -56,37 +82,60 @@ End cell. Section typing. Context `{typeG Σ}. - (* All of these are of course actual code in Rust, but somehow this is more fun. *) + (* Constructing a cell. *) + Definition cell_new : val := funrec: <> ["x"] := "return" ["x"]. - (* Constructing a cell is a coercion. *) - Lemma tctx_mk_cell E L ty p : - tctx_incl E L [p ◠ty] [p ◠cell ty]. + Lemma cell_new_type ty : + typed_instruction_ty [] [] [] cell_new + (fn (λ _, [])%EL (λ _, [# box ty]) (λ _:(), box (cell ty))). Proof. + apply type_fn; [apply _..|]. move=>/= _ ret arg. inv_vec arg=>x. simpl_subst. + eapply (type_jump [_]); first solve_typing. iIntros (???) "#LFT $ $ Hty". rewrite !tctx_interp_singleton /=. done. Qed. - (* Same for the other direction *) - Lemma tctx_unmk_cell E L ty p : - tctx_incl E L [p ◠cell ty] [p ◠ty]. + (* Same for the other direction. + FIXME : this does not exist in Rust.*) + Definition cell_into_inner : val := funrec: <> ["x"] := "return" ["x"]. + + Lemma cell_into_inner_type ty : + typed_instruction_ty [] [] [] cell_into_inner + (fn (λ _, [])%EL (λ _, [# box (cell ty)]) (λ _:(), box ty)). Proof. + apply type_fn; [apply _..|]. move=>/= _ ret arg. inv_vec arg=>x. simpl_subst. + eapply (type_jump [_]); first solve_typing. iIntros (???) "#LFT $ $ Hty". rewrite !tctx_interp_singleton /=. done. Qed. - Lemma read_cell E L κ ty : - Copy ty → lctx_lft_alive E L κ → - typed_read E L (&shr{κ} cell ty) ty (&shr{κ} cell ty). - Proof. intros ??. exact: read_shr. Qed. + (* Reading from a cell *) + Definition cell_get ty : val := + funrec: <> ["x"] := + let: "x'" := !"x" in + letalloc: "r" <-{ty.(ty_size)} !"x'" in + delete [ #1; "x"];; "return" ["r"]. - (* Writing actually needs code; typed_write can't have thread tokens. *) - Definition cell_write ty : val := + Lemma cell_get_type `(!Copy ty) : + typed_instruction_ty [] [] [] (cell_get ty) + (fn (λ α, [☀α])%EL (λ α, [# box (&shr{α} (cell ty))])%T (λ _, box ty)). + Proof. + apply type_fn; [apply _..|]. move=>/= α ret arg. inv_vec arg=>x. simpl_subst. + eapply type_deref; [solve_typing..|apply read_own_move|done|]=>x'. simpl_subst. + eapply type_letalloc_n; [solve_typing..| |solve_typing|intros r; simpl_subst]. + { apply (read_shr _ _ _ (cell ty)); solve_typing. } + eapply type_delete; [solve_typing..|]. + eapply (type_jump [_]); solve_typing. + Qed. + + (* Writing to a cell *) + Definition cell_set ty : val := funrec: <> ["c"; "x"] := let: "c'" := !"c" in "c'" <-{ty.(ty_size)} !"x";; let: "r" := new [ #0 ] in delete [ #1; "c"] ;; delete [ #ty.(ty_size); "x"] ;; "return" ["r"]. - Lemma cell_write_type ty : - typed_instruction_ty [] [] [] (cell_write ty) + Lemma cell_set_type ty : + typed_instruction_ty [] [] [] (cell_set ty) (fn (λ α, [☀α])%EL (λ α, [# box (&shr{α} cell ty); box ty]) (λ α, box unit)). Proof. @@ -101,19 +150,20 @@ Section typing. rewrite tctx_interp_cons tctx_interp_singleton !tctx_hasty_val. iIntros "[Hc' Hx]". rewrite {1}/elctx_interp big_opL_singleton /=. iDestruct "Hc'" as (l) "[EQ #Hshr]". iDestruct "EQ" as %[=->]. + iDestruct "Hshr" as (P) "[#HP #Hshr]". iDestruct "Hx" as (l') "[EQ [Hown >H†]]". iDestruct "EQ" as %[=->]. iDestruct "Hown" as (vl') "[>H↦' Hown']". iMod (na_bor_acc with "LFT Hshr HE Htl") as "(Hown & Htl & Hclose)"; [solve_ndisj..|]. - iDestruct "Hown" as (vl) "[>H↦ Hown]". + iDestruct ("HP" with "Hown") as (vl) "[>H↦ Hown]". iDestruct (ty_size_eq with "Hown") as "#>%". iDestruct (ty_size_eq with "Hown'") as "#>%". iApply wp_fupd. iApply (wp_memcpy with "[$HEAP $H↦ $H↦']"); [done..|]. iNext. iIntros "[H↦ H↦']". rewrite {1}/elctx_interp big_opL_singleton /=. iMod ("Hclose" with "[H↦ Hown'] Htl") as "[$ $]". - { iExists vl'. by iFrame. } + { iApply "HP". iExists vl'. by iFrame. } rewrite tctx_interp_cons tctx_interp_singleton !tctx_hasty_val' //. iSplitR; iModIntro. - - iExists _. iSplit; done. + - iExists _. simpl. eauto. - iExists _. iSplit; first done. iFrame. iExists _. iFrame. rewrite uninit_own. auto. } intros v. simpl_subst. clear v. @@ -124,5 +174,20 @@ Section typing. eapply (type_jump [_]); solve_typing. Qed. - (* TODO: get_mut *) + (* Reading from a cell *) + Definition cell_get_mut : val := + funrec: <> ["x"] := "return" ["x"]. + + Lemma cell_get_mut_type `(!Copy ty) : + typed_instruction_ty [] [] [] cell_get_mut + (fn (λ α, [☀α])%EL (λ α, [# box (&uniq{α} (cell ty))])%T + (λ α, box (&uniq{α} ty))%T). + Proof. + apply type_fn; [apply _..|]. move=>/= α ret arg. inv_vec arg=>x. simpl_subst. + eapply (type_jump [_]). solve_typing. rewrite /tctx_incl /=. + iIntros (???) "_ $$". rewrite !tctx_interp_singleton /tctx_elt_interp /=. + by iIntros "$". + Qed. End typing. + +Hint Resolve cell_mono' cell_proper' : lrust_typing. -- GitLab