From 5f783157a3e6bdb6a82567e49942199e7c1175fe Mon Sep 17 00:00:00 2001 From: Jacques-Henri Jourdan <jjourdan@mpi-sws.org> Date: Thu, 8 Dec 2016 00:01:06 +0100 Subject: [PATCH] Fix build by indexing own by the full size and defining [freeable_sz]. Warning : splitting a own of a product only works if the list of types is non-empty. --- theories/lang/new_delete.v | 2 +- theories/typing/own.v | 62 ++++++++++++++++++++++-------- theories/typing/product_split.v | 67 ++++++++++++--------------------- 3 files changed, 72 insertions(+), 59 deletions(-) diff --git a/theories/lang/new_delete.v b/theories/lang/new_delete.v index c8f3a54e..e42cc6b0 100644 --- a/theories/lang/new_delete.v +++ b/theories/lang/new_delete.v @@ -31,7 +31,7 @@ Section specs. Lemma wp_delete E (n:Z) l vl : ↑heapN ⊆ E → n = length vl → - {{{ heap_ctx ∗ â–· l ↦∗ vl ∗ (â–· †l…(length vl) ∨ ⌜n = 0âŒ) }}} + {{{ heap_ctx ∗ l ↦∗ vl ∗ (†l…(length vl) ∨ ⌜n = 0âŒ) }}} delete [ #n; #l] @ E {{{ RET LitV LitUnit; True }}}. Proof. diff --git a/theories/typing/own.v b/theories/typing/own.v index df57f932..5ac4a286 100644 --- a/theories/typing/own.v +++ b/theories/typing/own.v @@ -1,3 +1,4 @@ +From Coq Require Import Qcanon. From iris.proofmode Require Import tactics. From lrust.lifetime Require Import borrow frac_borrow. From lrust.lang Require Export new_delete. @@ -13,7 +14,37 @@ Section own. {| st_size := 1; st_own tid vl := ⌜length vl = 1%natâŒ%I |}. Next Obligation. done. Qed. - Program Definition own (q : Qp) (ty : type) := + Program Definition freeable_sz (n : nat) (sz : nat) (l : loc) : iProp Σ := + match sz, n return _ with + | 0%nat, _ => True + | _, 0%nat => False + | sz, n => †{mk_Qp (sz / n) _}l…sz + end%I. + Next Obligation. intros _ _ _ sz0 ? n ?. by apply Qcmult_pos_pos. Qed. + Global Instance freable_sz_timeless n sz l : TimelessP (freeable_sz n sz l). + Proof. destruct sz, n; apply _. Qed. + + Lemma freeable_sz_full n l : freeable_sz n n l ⊣⊢ (†{1}l…n ∨ ⌜Z.of_nat n = 0âŒ)%I. + Proof. + destruct n. + - iSplit; iIntros "H /="; auto. + - assert (Z.of_nat (S n) = 0 ↔ False) as -> by done. rewrite right_id. + rewrite /freeable_sz (proj2 (Qp_eq (mk_Qp _ _) 1)) //= Qcmult_inv_r //. + Qed. + + Lemma freeable_sz_split n sz1 sz2 l : + freeable_sz n sz1 l ∗ freeable_sz n sz2 (shift_loc l sz1) ⊣⊢ + freeable_sz n (sz1 + sz2) l. + Proof. + destruct sz1; [|destruct sz2;[|rewrite /freeable_sz plus_Sn_m; destruct n]]. + - by rewrite left_id shift_loc_0. + - by rewrite right_id Nat.add_0_r. + - iSplit. by iIntros "[[]?]". by iIntros "[]". + - rewrite heap_freeable_op_eq. f_equiv. apply Qp_eq. + rewrite /= -Qcmult_plus_distr_l -Z2Qc_inj_add /Z.add. do 3 f_equal. lia. + Qed. + + Program Definition own (n : nat) (ty : type) := {| ty_size := 1; ty_own tid vl := (* We put a later in front of the †{q}, because we cannot use @@ -23,7 +54,7 @@ Section own. Since this assertion is timeless, this should not cause problems. *) (∃ l:loc, ⌜vl = [ #l ]⌠∗ â–· l ↦∗: ty.(ty_own) tid ∗ - â–· (†{q}l…ty.(ty_size) ∨ ⌜ty.(ty_size) = 0%natâŒ))%I; + â–· freeable_sz n ty.(ty_size) l)%I; ty_shr κ tid E l := (∃ l':loc, &frac{κ}(λ q', l ↦{q'} #l') ∗ â–¡ (∀ q' F, ⌜E ∪ mgmtE ⊆ F⌠→ @@ -67,8 +98,8 @@ Section own. by iApply (ty.(ty_shr_mono) with "LFT Hκ"). Qed. - Lemma ty_incl_own Ï ty1 ty2 q : - ty_incl Ï ty1 ty2 → ty_incl Ï (own q ty1) (own q ty2). + Lemma ty_incl_own n ty1 ty2 Ï : + ty_incl Ï ty1 ty2 → ty_incl Ï (own n ty1) (own n ty2). Proof. iIntros (Hincl tid) "#LFT H/=". iMod (Hincl with "LFT H") as "[#Howni #Hshri]". iModIntro. iSplit; iIntros "!#*H". @@ -85,7 +116,7 @@ Section own. Qed. Lemma typed_new Ï (n : nat): - 0 ≤ n → typed_step_ty Ï (new [ #n]%E) (own 1 (Î (replicate n uninit))). + 0 ≤ n → typed_step_ty Ï (new [ #n]%E) (own n (Î (replicate n uninit))). Proof. iIntros (Hn tid) "!#(#HEAP&_&_&$)". iApply (wp_new with "HEAP"); try done. iIntros "!>*(% & H†& H↦)". iExists _. iSplit. done. iNext. @@ -97,11 +128,11 @@ Section own. iExists [v], vl. iSplit. done. by iSplit. - assert (ty_size (Î (replicate n uninit)) = n) as ->. { clear. induction n; rewrite //= IHn //. } - iDestruct "H†" as "[?|%]". by auto. rewrite (inj Z.of_nat n 0%nat); auto. + by rewrite freeable_sz_full. Qed. Lemma typed_delete ty (ν : expr): - typed_step (ν â— own 1 ty) (delete [ #ty.(ty_size); ν])%E (λ _, top). + typed_step (ν â— own ty.(ty_size) ty) (delete [ #ty.(ty_size); ν])%E (λ _, top). Proof. iIntros (tid) "!#(#HEAP&_&Hâ—&$)". wp_bind ν. iApply (has_type_wp with "[$Hâ—]"). iIntros (v) "_ Hâ— !>". @@ -110,13 +141,12 @@ Section own. iDestruct "H↦∗:" as (vl) "[>H↦ Hown]". rewrite ty_size_eq. iDestruct "Hown" as ">Hown". iDestruct "Hown" as %<-. iApply (wp_delete with "[-]"); try by auto. - iFrame "∗#". iDestruct "H†" as "[?|Hlen]". by auto. - iDestruct "Hlen" as %->. auto. + rewrite freeable_sz_full. by iFrame. Qed. - Lemma update_strong ty1 ty2 q: + Lemma update_strong ty1 ty2 n: ty1.(ty_size) = ty2.(ty_size) → - update ty1 (λ ν, ν â— own q ty2)%P (λ ν, ν â— own q ty1)%P. + update ty1 (λ ν, ν â— own n ty2)%P (λ ν, ν â— own n ty1)%P. Proof. iIntros (Hsz ν tid Φ E ?) "_ Hâ— HΦ". iApply (has_type_wp with "Hâ—"). iIntros (v) "Hνv Hâ—". iDestruct "Hνv" as %Hνv. @@ -127,8 +157,8 @@ Section own. iExists _. iSplit. done. iFrame. iExists _. iFrame. Qed. - Lemma consumes_copy_own ty q: - Copy ty → consumes ty (λ ν, ν â— own q ty)%P (λ ν, ν â— own q ty)%P. + Lemma consumes_copy_own ty n: + Copy ty → consumes ty (λ ν, ν â— own n ty)%P (λ ν, ν â— own n ty)%P. Proof. iIntros (? ν tid Φ E ?) "_ Hâ— Htl HΦ". iApply (has_type_wp with "Hâ—"). iIntros (v) "Hνv Hâ—". iDestruct "Hνv" as %Hνv. @@ -140,9 +170,9 @@ Section own. rewrite /has_type Hνv. iExists _. iSplit. done. iFrame. iExists vl. eauto. Qed. - Lemma consumes_move ty q: - consumes ty (λ ν, ν â— own q ty)%P - (λ ν, ν â— own q (Î (replicate ty.(ty_size) uninit)))%P. + Lemma consumes_move ty n: + consumes ty (λ ν, ν â— own n ty)%P + (λ ν, ν â— own n (Î (replicate ty.(ty_size) uninit)))%P. Proof. iIntros (ν tid Φ E ?) "_ Hâ— Htl HΦ". iApply (has_type_wp with "Hâ—"). iIntros (v) "Hνv Hâ—". iDestruct "Hνv" as %Hνv. diff --git a/theories/typing/product_split.v b/theories/typing/product_split.v index 83b0406a..63039819 100644 --- a/theories/typing/product_split.v +++ b/theories/typing/product_split.v @@ -13,17 +13,17 @@ Section product_split. | ty :: q => (ty, accu) :: combine_offs q (accu + ty.(ty_size)) end. - Lemma perm_split_own_prod2 ty1 ty2 (q1 q2 : Qp) ν : - ν â— own (q1 + q2) (product2 ty1 ty2) ⇔ - ν â— own q1 ty1 ∗ ν +â‚— #ty1.(ty_size) â— own q2 ty2. + Lemma perm_split_own_prod2 ty1 ty2 n ν : + ν â— own n (product2 ty1 ty2) ⇔ + ν â— own n ty1 ∗ ν +â‚— #ty1.(ty_size) â— own n ty2. Proof. rewrite /has_type /own /sep /=. destruct (eval_expr ν) as [[[]|?]|]; last first; split; iIntros (tid) "_ H/="; (try by iDestruct "H" as "[_ []]"); (try by iDestruct "H" as (l) "[% _]"). { by auto. } - - iDestruct "H" as (l') "(EQ & H & H†)". iDestruct "EQ" as %[=<-]. - iDestruct "H" as (vl) "[H↦ H]". iDestruct "H" as (vl1 vl2) "(>% & H1 & H2)". - subst. rewrite heap_mapsto_vec_app -heap_freeable_op_eq. + - iDestruct "H" as (l') "(EQ & H & >H†)". iDestruct "EQ" as %[=<-]. + iDestruct "H" as (vl) "[>H↦ H]". iDestruct "H" as (vl1 vl2) "(>% & H1 & H2)". + subst. rewrite heap_mapsto_vec_app -freeable_sz_split. iDestruct "H†" as "[H†1 H†2]". iDestruct "H↦" as "[H↦1 H↦2]". iAssert (â–· ⌜length vl1 = ty_size ty1âŒ)%I with "[#]" as ">EQ". { iNext. by iApply ty_size_eq. } @@ -33,7 +33,7 @@ Section product_split. - iDestruct "H" as "[H1 H2]". iDestruct "H1" as (l') "(EQ & H↦1 & H†1)". iDestruct "EQ" as %[=<-]. iDestruct "H2" as (l') "(EQ & H↦2 & H†2)". iDestruct "EQ" as %[=<-]. - iExists l. iSplitR. done. rewrite -heap_freeable_op_eq. iFrame. + iExists l. iSplitR. done. rewrite -freeable_sz_split. iFrame. iDestruct "H↦1" as (vl1) "[H↦1 H1]". iDestruct "H↦2" as (vl2) "[H↦2 H2]". iExists (vl1 ++ vl2). rewrite heap_mapsto_vec_app. iFrame. iAssert (â–· ⌜length vl1 = ty_size ty1âŒ)%I with "[#]" as ">EQ". @@ -41,49 +41,32 @@ Section product_split. iDestruct "EQ" as %->. iFrame. iExists vl1, vl2. iFrame. auto. Qed. - Lemma perm_split_own_prod tyl (q : Qp) (ql : list Qp) ν : - length tyl = length ql → - foldr (λ (q : Qp) acc, q + acc)%Qc 0%Qc ql = q → - ν â— own q (Î tyl) ⇔ + Lemma perm_split_own_prod tyl n ν : + tyl ≠[] → + ν â— own n (Î tyl) ⇔ foldr (λ qtyoffs acc, - ν +â‚— #(qtyoffs.2.2:nat) â— own (qtyoffs.1) (qtyoffs.2.1) ∗ acc) - ⊤ (combine ql (combine_offs tyl 0)). + ν +â‚— #(qtyoffs.2:nat) â— own n (qtyoffs.1) ∗ acc) + ⊤ (combine_offs tyl 0). Proof. - revert q tyl ν. induction ql as [|q0 [|q1 ql] IH]=>q tyl ν Hlen Hq. - { destruct q. intros. simpl in *. by subst. } - - destruct tyl as [|ty0 [|ty1 tyl]]; try done. simpl in *. - assert (q0 = q) as ->. { apply Qp_eq. by rewrite -Hq Qcplus_0_r. } - rewrite /has_type /sep /=. + intros ?. revert ν. rewrite /product /=. induction tyl as [|ty tyl IH]=>ν. done. + rewrite /= perm_split_own_prod2. destruct tyl. + - rewrite /has_type /sep /=. destruct (eval_expr ν) as [[[]|]|]; split; iIntros (tid) "_ H/="; - (try by iDestruct "H" as "[[] _]"); (try by iDestruct "H" as (l) "[% _]"); - (try by auto); rewrite (shift_loc_0 l) Nat.add_0_r. - + iSplitL; last done. iExists _. iSplitR. done. - iDestruct "H" as (l') "[Heq [H↦ H†]]". iDestruct "Heq" as %[=<-]. - iDestruct "H↦" as (vl) "[H↦ H]". - iDestruct "H" as (vl1 vl2) "(>% & Hown & >%)". subst. - rewrite app_nil_r. iFrame. iExists _. by iFrame. - + iExists l. iSplitR. done. - iDestruct "H" as "[H _]". iDestruct "H" as (l') "[Heq [H↦ H†]]". - iDestruct "Heq" as %[=<-]. iFrame. iDestruct "H↦" as (vl) "[H↦ Hown]". - iExists vl. iFrame. iExists vl, []. iFrame. rewrite app_nil_r. auto. - - destruct tyl as [|ty0 tyl]. done. - assert (Hpos : (0 < foldr (λ (q : Qp) acc, (q + acc)%Qc) 0%Qc (q1 :: ql))%Qc). - { apply Qcplus_pos_nonneg. apply Qp_prf. clear. induction ql. done. - apply Qcplus_nonneg_nonneg. apply Qclt_le_weak, Qp_prf. done. } - assert (q = q0 + mk_Qp _ Hpos)%Qp as ->. by by apply Qp_eq; rewrite -Hq. - injection Hlen; intro Hlen'. rewrite perm_split_own_prod2 IH //. - set (q1l := q1::ql). cbn[combine_offs combine foldr]. apply perm_sep_proper. + (try by iDestruct "H" as "[_ []]"); (try by iDestruct "H" as "[[] _]"); + rewrite shift_loc_0; iDestruct "H" as "[$ _]"; [done|]. + iExists _. iSplitL. done. iSplitL; iIntros "!>!>"; last done. + iExists []. rewrite heap_mapsto_vec_nil. auto. + - rewrite IH //. f_equiv. + rewrite /has_type /sep /=. destruct (eval_expr ν) as [[[]|]|]; split; iIntros (tid) "_ H/="; - (try by iDestruct "H" as "[]"); (try by iDestruct "H" as (l) "[% _]"); - (try by auto); by rewrite shift_loc_0. - + cut (length tyl = length (q1 :: ql)); last done. clear. revert tyl. - generalize 0%nat. induction (q1 :: ql)=>offs -[|ty tyl] Hlen //=. - apply perm_sep_proper. + (try by iDestruct "H" as "[]"); (try by iDestruct "H" as (l) "[% _]"); + (try by auto); rewrite (shift_loc_0 l) //. + + clear. change (ty_size ty) with (0+ty_size ty)%nat at 2. generalize 0%nat. + induction (t :: tyl) as [|ty' tyl' IH]=>offs //=. apply perm_sep_proper. * rewrite /has_type /sep /=. destruct (eval_expr ν) as [[[]|]|]; split; iIntros (tid) "_ H/="; (try by iDestruct "H" as "[]"); [|]; by rewrite shift_loc_assoc_nat (comm plus). - * etrans. apply IHl. by injection Hlen. do 3 f_equiv. lia. + * etrans. apply IH. do 2 f_equiv. lia. Qed. Lemma perm_split_uniq_bor_prod2 ty1 ty2 κ ν : -- GitLab