diff --git a/theories/typing/lib/slice/iter.v b/theories/typing/lib/slice/iter.v index 4d6bc33e88fa69b5955f9dee9f5f533104b64893..b032044fded10303a5c93e1613e21558c3226474 100644 --- a/theories/typing/lib/slice/iter.v +++ b/theories/typing/lib/slice/iter.v @@ -30,6 +30,68 @@ Section iter. "it" <- "l" +ₗ #ty.(ty_size);; "it" +ₗ #1 <- "len" - #1;; let: "r" := new [ #2] in "r" <-{Σ 1} "l";; return: ["r"]. + (* Rust's Iter::next *) + Lemma iter_shr_next_type {𝔄} (ty: type 𝔄) : + typed_val (iter_next ty) + (fn<(α, β)>(∅; &uniq{β} (iter_shr α ty)) → option_ty (&shr{α} ty)) + (λ post '-[(al, al')], al' = tail al → post (hd_error al)). + Proof. + eapply type_fn; [apply _|]. move=>/= [α β]??[b[]]. simpl_subst. + iIntros (?[vπ[]]?) "#LFT TIME #PROPH #UNIQ #E Na L C /=[b _] #Obs". + rewrite tctx_hasty_val. iDestruct "b" as ([|]) "[#⧖' box]"=>//. + case b as [[|b|]|]=>//=. rewrite split_mt_uniq_bor. + iDestruct "box" as "[(#In' & %it &%& %ξi &>[% %Eq2]& >↦b & Vo & Bor) †b]". + set ξ := PrVar _ ξi. wp_read. + iMod (lctx_lft_alive_tok β with "E L") as (?) "(β & L & ToL)"; [solve_typing..|]. + iMod (bor_acc with "LFT Bor β") as "[big ToBor]"; [done|]. wp_let. + iDestruct "big" as (? d') "(#⧖ & Pc & ↦it)". rewrite split_mt_shr_slice. + case d' as [|]=>//=. iDestruct "↦it" as (? len aπl->) "(↦ & ↦' & tys)". + rewrite freeable_sz_full -heap_mapsto_vec_singleton. + wp_apply (wp_delete with "[$↦b $†b]"); [done|]. iIntros "_". wp_seq. + iDestruct (uniq_agree with "Vo Pc") as %[Eq1 ->]. wp_op. wp_read. wp_let. + wp_op. wp_case. case len as [|]=>/=. + { iMod ("ToBor" with "[Pc ↦ ↦' tys]") as "[Bor β]". + { iNext. iExists _, _. rewrite split_mt_shr_slice. iFrame "⧖ Pc". + iExists _, _, _. by iFrame. } + iMod ("ToL" with "β L") as "L". + iApply (type_type +[#it ◁ &uniq{β} (iter_shr α ty)] -[vπ] + with "[] LFT TIME PROPH UNIQ E Na L C [-] []"). + - iApply type_new; [done|]. intro_subst. + iApply (type_sum_unit +[(); &shr{_} _]%T 0%fin); + [done|solve_extract|solve_typing..|]. + iApply type_jump; [solve_typing|solve_extract|solve_typing]. + - rewrite/= !(tctx_hasty_val #_). iSplitL; [|done]. iExists _. + iFrame "⧖' In'". iExists _, _. iFrame. iPureIntro. split; [lia|done]. + - iApply proph_obs_eq; [|done]=> π. move: (equal_f Eq1 π)=>/=. + case (vπ π)=>/= ??->. by inv_vec aπl. } + inv_vec aπl. move=> aπ aπl' Eq1 /=. + wp_read. wp_let. wp_op. wp_write. do 2 wp_op. wp_write. + have ->: S len - 1 = len by lia. + have ->: vπ = λ π, (aπ π :: lapply aπl' π, π ξ). + { by rewrite [vπ]surjective_pairing_fun Eq1 Eq2. } + iDestruct "tys" as "[ty tys]". rewrite shift_loc_0. + iMod (uniq_update with "UNIQ Vo Pc") as "[Vo Pc]"; [done|]. + iMod ("ToBor" with "[Pc ↦ ↦' tys]") as "[Bor β]". + { iNext. iExists _, _. rewrite split_mt_shr_slice. iFrame "⧖ Pc". + iExists _, _, _. iFrame "↦ ↦'". iSplit; [done|]. + setoid_rewrite <-shift_loc_assoc_nat. by iFrame. } + iMod ("ToL" with "β L") as "L". + iApply (type_type +[#it ◁ &uniq{β} (iter_shr α ty); #l ◁ &shr{α} ty] + -[λ π, (lapply aπl' π, π ξ); aπ] + with "[] LFT TIME PROPH UNIQ E Na L C [-] []"). + - iApply type_new; [done|]. intro_subst. + iApply (type_sum_assign +[(); &shr{_} _]%T 1%fin); + [done|solve_extract|solve_typing..|]. + iApply type_jump; [solve_typing|solve_extract|solve_typing]. + - rewrite/= !(tctx_hasty_val #_). iSplitL "Vo Bor"; [|iSplitL; [|done]]. + + iExists _. iFrame "⧖ In'". iExists _, _. rewrite /uniq_body. + rewrite (proof_irrel (@prval_to_inh (listₛ _) (lapply aπl')) + (@prval_to_inh (listₛ _) (fst ∘ vπ))). + by iFrame. + + iExists _. iFrame "⧖". iApply ty_shr_depth_mono; [|done]. lia. + - done. + Qed. + (* Rust's IterMut::next *) Lemma iter_uniq_next_type {𝔄} (ty: type 𝔄) : typed_val (iter_next ty) @@ -77,8 +139,7 @@ Section iter. iExists _, _, _, aπζil'. setoid_rewrite <-shift_loc_assoc_nat. by iFrame. } iMod ("ToL" with "β L") as "L". set aaπl' := vmap _ aπζil'. rewrite /uniq_body. set ζ := PrVar _ ζi. - iApply (type_type - +[#it ◁ &uniq{β} (iter_uniq α ty); #l ◁ &uniq{α} ty] + iApply (type_type +[#it ◁ &uniq{β} (iter_uniq α ty); #l ◁ &uniq{α} ty] -[λ π, (lapply aaπl' π, π ξ); λ π, (aπ π, π ζ)] with "[] LFT TIME PROPH UNIQ E Na L C [-] []"). - iApply type_new; [done|]. intro_subst. @@ -105,6 +166,72 @@ Section iter. let: "l'" := !"it" +ₗ "len'" * #ty.(ty_size) in let: "r" := new [ #2] in "r" <-{Σ 1} "l'";; return: ["r"]. + (* Rust's Iter::next_back *) + Lemma iter_shr_next_back_type {𝔄} (ty: type 𝔄) : + typed_val (iter_next_back ty) + (fn<(α, β)>(∅; &uniq{β} (iter_shr α ty)) → option_ty (&shr{α} ty)) + (λ post '-[(al, al')], al' = removelast al → post (last_error al)). + Proof. + eapply type_fn; [apply _|]. move=>/= [α β]??[b[]]. simpl_subst. + iIntros (?[vπ[]]?) "#LFT TIME #PROPH #UNIQ #E Na L C /=[b _] #Obs". + rewrite tctx_hasty_val. iDestruct "b" as ([|]) "[#⧖' box]"=>//. + case b as [[|b|]|]=>//=. rewrite split_mt_uniq_bor. + iDestruct "box" as "[(#In' & %it &%& %ξi &>[% %Eq2]& >↦b & Vo & Bor) †b]". + set ξ := PrVar _ ξi. wp_read. + iMod (lctx_lft_alive_tok β with "E L") as (?) "(β & L & ToL)"; [solve_typing..|]. + iMod (bor_acc with "LFT Bor β") as "[big ToBor]"; [done|]. wp_let. + iDestruct "big" as (? d') "(#⧖ & Pc & ↦it)". rewrite split_mt_shr_slice. + case d' as [|]=>//=. iDestruct "↦it" as (? len aπl->) "(↦ & ↦' & tys)". + rewrite freeable_sz_full -heap_mapsto_vec_singleton. + wp_apply (wp_delete with "[$↦b $†b]"); [done|]. iIntros "_". wp_seq. + iDestruct (uniq_agree with "Vo Pc") as %[Eq1 ->]. wp_op. wp_read. wp_let. + wp_op. wp_case. case len as [|]=>/=. + { iMod ("ToBor" with "[Pc ↦ ↦' tys]") as "[Bor β]". + { iNext. iExists _, _. rewrite split_mt_shr_slice. iFrame "⧖ Pc". + iExists _, _, _. by iFrame. } + iMod ("ToL" with "β L") as "L". + iApply (type_type +[#it ◁ &uniq{β} (iter_shr α ty)] -[vπ] + with "[] LFT TIME PROPH UNIQ E Na L C [-] []"). + - iApply type_new; [done|]. intro_subst. + iApply (type_sum_unit +[(); &shr{_} _]%T 0%fin); + [done|solve_extract|solve_typing..|]. + iApply type_jump; [solve_typing|solve_extract|solve_typing]. + - rewrite/= !(tctx_hasty_val #_). iSplitL; [|done]. iExists _. + iFrame "⧖' In'". iExists _, _. iFrame. iPureIntro. split; [lia|done]. + - iApply proph_obs_eq; [|done]=> π. move: (equal_f Eq1 π)=>/=. + case (vπ π)=>/= ??->. by inv_vec aπl. } + iDestruct (big_sepL_vinitlast with "tys") as "[tys ty]". + set aπl' := vinit _. set aπ := vlast _. + wp_op. wp_let. wp_op. wp_write. wp_read. do 2 wp_op. wp_let. + have ->: S len - 1 = len by lia. rewrite -Nat2Z.inj_mul. + have ->: vπ = λ π, (lapply aπl π, π ξ). + { by rewrite [vπ]surjective_pairing_fun Eq1 Eq2. } + iMod (uniq_update with "UNIQ Vo Pc") as "[Vo Pc]"; [done|]. + iMod ("ToBor" with "[Pc ↦ ↦' tys]") as "[Bor β]". + { iNext. iExists _, _. rewrite split_mt_shr_slice. iFrame "⧖ Pc". + iExists _, _, _. by iFrame. } + iMod ("ToL" with "β L") as "L". + iApply (type_type +[#it ◁ &uniq{β} (iter_shr α ty); #(l +ₗ[ty] len) ◁ &shr{α} ty] + -[λ π, (lapply aπl' π, π ξ); aπ] + with "[] LFT TIME PROPH UNIQ E Na L C [-] []"). + - iApply type_new; [done|]. intro_subst. + iApply (type_sum_assign +[(); &shr{_} _]%T 1%fin); + [done|solve_extract|solve_typing..|]. + iApply type_jump; [solve_typing|solve_extract|solve_typing]. + - rewrite/= !(tctx_hasty_val #_). iSplitL "Vo Bor"; [|iSplitL; [|done]]. + + iExists _. iFrame "⧖ In'". iExists _, _. rewrite /uniq_body. + rewrite (proof_irrel (@prval_to_inh (listₛ _) (lapply aπl')) + (@prval_to_inh (listₛ _) (fst ∘ vπ))). + by iFrame. + + iExists _. iFrame "⧖". iApply ty_shr_depth_mono; [|done]. lia. + - iApply proph_obs_impl; [|done]=>/= π. clear. + have ->: last_error (lapply aπl π) = Some (aπ π). + { inv_vec aπl=>/= + aπl'. by elim aπl'; [done|]=>/= *. } + have ->: removelast (lapply aπl π) = lapply aπl' π. + { inv_vec aπl=>/= + aπl'. elim aπl'; [done|]=>/= *. by f_equal. } + done. + Qed. + (* Rust's IterMut::next_back *) Lemma iter_uniq_next_back_type {𝔄} (ty: type 𝔄) : typed_val (iter_next_back ty) @@ -142,19 +269,18 @@ Section iter. case (vπ π)=>/= ??->. move: (aaπl)=> aaπl'. inv_vec aaπl'=>/= [Imp ?]. by apply Imp. } iDestruct (big_sepL_vinitlast with "uniqs") as "[uniqs uniq]". + set aπζil' := vinit _. set aπζi := vlast _. wp_op. wp_let. wp_op. wp_write. wp_read. do 2 wp_op. wp_let. have ->: S len - 1 = len by lia. rewrite -Nat2Z.inj_mul. have ->: vπ = λ π, (lapply aaπl π, π ξ). { by rewrite [vπ]surjective_pairing_fun Eq1 Eq2. } - set aπζil' := vinit _. set aπζi := vlast _. iMod (uniq_update with "UNIQ Vo Pc") as "[Vo Pc]"; [done|]. iMod ("ToBor" with "[Pc ↦ ↦' uniqs]") as "[Bor β]". { iNext. iExists _, _. rewrite split_mt_uniq_slice. iFrame "⧖ Pc In". iExists _, _, _, aπζil'. by iFrame. } iMod ("ToL" with "β L") as "L". set aaπl' := vmap _ aπζil'. rewrite /uniq_body. set ζ := PrVar _ aπζi.2. - iApply (type_type - +[#it ◁ &uniq{β} (iter_uniq α ty); #(l +ₗ[ty] len) ◁ &uniq{α} ty] + iApply (type_type +[#it ◁ &uniq{β} (iter_uniq α ty); #(l +ₗ[ty] len) ◁ &uniq{α} ty] -[λ π, (lapply aaπl' π, π ξ); λ π, (aπζi.1 π, π ζ)] with "[] LFT TIME PROPH UNIQ E Na L C [-] []"). - iApply type_new; [done|]. intro_subst.