diff --git a/theories/typing/function.v b/theories/typing/function.v index b052b08f5d663475da6706c5734971edcee32b05..d0eff2616b95631b9bc9c6331bce35a8d5fcabca 100644 --- a/theories/typing/function.v +++ b/theories/typing/function.v @@ -109,7 +109,26 @@ Section typing. (∀ x, subtype (E0 ++ E x) L0 (ty1 x) (ty2 x)) → subtype E0 L0 (fn E tys1 ty1) (fn E tys2 ty2). Proof. - intros. apply fn_subtype_full; try done. intros. apply elctx_incl_refl. + intros. apply fn_subtype_full; try done. + Qed. + + (* This proper and the next can probably not be inferred, but oh well. *) + Global Instance fn_subtype_ty' {A n} E0 L0 E : + Proper (flip (pointwise_relation A (λ (v1 v2 : vec type n), Forall2 (subtype E0 L0) v1 v2)) ==> + pointwise_relation A (subtype E0 L0) ==> subtype E0 L0) (fn E). + Proof. + intros tys1 tys2 Htys ty1 ty2 Hty. apply fn_subtype_ty. + - intros. eapply Forall2_impl; first eapply Htys. intros ??. + eapply subtype_weaken; last done. by apply contains_inserts_r. + - intros. eapply subtype_weaken, Hty; last done. by apply contains_inserts_r. + Qed. + + Global Instance fn_eqtype_ty' {A n} E0 L0 E : + Proper (pointwise_relation A (λ (v1 v2 : vec type n), Forall2 (eqtype E0 L0) v1 v2) ==> + pointwise_relation A (eqtype E0 L0) ==> eqtype E0 L0) (fn E). + Proof. + intros tys1 tys2 Htys ty1 ty2 Hty. split; eapply fn_subtype_ty'; try (by intro; apply Hty); + intros x; (apply Forall2_flip + idtac); (eapply Forall2_impl; first by eapply (Htys x)); by intros ??[]. Qed. Lemma fn_subtype_elctx_sat {A n} E0 L0 E E' (tys : A → vec type n) ty : @@ -126,7 +145,7 @@ Section typing. intros Hκκ'. apply fn_subtype_full; try done. intros. apply elctx_incl_lft_incl; last by apply elctx_incl_refl. iIntros "#HE #HL". iApply (Hκκ' with "[HE] HL"). - rewrite /elctx_interp_0 big_sepL_app. iDestruct "HE" as "[_ $]". + rewrite /elctx_interp_0 big_sepL_app. iDestruct "HE" as "[$ _]". Qed. Lemma fn_subtype_specialize {A B n} (σ : A → B) E0 L0 E tys ty : diff --git a/theories/typing/lft_contexts.v b/theories/typing/lft_contexts.v index 2441c89bc44ef019206dbb76b2a73e941bfc227b..99c198c10f006d2de17f3e14eccac938623d0019 100644 --- a/theories/typing/lft_contexts.v +++ b/theories/typing/lft_contexts.v @@ -311,7 +311,10 @@ End lft_contexts. Section elctx_incl. (* External lifetime context inclusion, in a persistent context. - (Used for function types subtyping). *) + (Used for function types subtyping). + On paper, this corresponds to using only the inclusions from E, L + to show E1; [] |- E2. + *) Context `{invG Σ, lftG Σ} (E : elctx) (L : llctx). @@ -320,8 +323,19 @@ Section elctx_incl. ∀ qE1, elctx_interp E1 qE1 ={F}=∗ ∃ qE2, elctx_interp E2 qE2 ∗ (elctx_interp E2 qE2 ={F}=∗ elctx_interp E1 qE1). + Global Instance elctx_incl_preorder : PreOrder elctx_incl. + Proof. + split. + - iIntros (???) "_ _ * ?". iExists _. iFrame. eauto. + - iIntros (x y z Hxy Hyz ??) "#HE #HL * HE1". + iMod (Hxy with "HE HL * HE1") as (qy) "[HE1 Hclose1]"; first done. + iMod (Hyz with "HE HL * HE1") as (qz) "[HE1 Hclose2]"; first done. + iModIntro. iExists qz. iFrame "HE1". iIntros "HE1". + iApply ("Hclose1" with ">"). iApply "Hclose2". done. + Qed. + Lemma elctx_incl_refl E' : elctx_incl E' E'. - Proof. iIntros (??) "_ _ * ?". iExists _. iFrame. eauto. Qed. + Proof. reflexivity. Qed. Lemma elctx_incl_nil E' : elctx_incl E' []. Proof. @@ -329,22 +343,50 @@ Section elctx_incl. rewrite /elctx_interp big_sepL_nil. auto. Qed. + Global Instance elctx_incl_app : + Proper (elctx_incl ==> elctx_incl ==> elctx_incl) app. + Proof. + iIntros (?? HE1 ?? HE2 ??) "#HE #HL *". rewrite {1}/elctx_interp big_sepL_app. + iIntros "[HE1 HE2]". + iMod (HE1 with "HE HL * HE1") as (q1) "[HE1 Hclose1]"; first done. + iMod (HE2 with "HE HL * HE2") as (q2) "[HE2 Hclose2]"; first done. + destruct (Qp_lower_bound q1 q2) as (q & ? & ? & -> & ->). + iModIntro. iExists q. rewrite /elctx_interp !big_sepL_app. + iDestruct "HE1" as "[$ HE1]". iDestruct "HE2" as "[$ HE2]". + iIntros "[HE1' HE2']". + iMod ("Hclose1" with "[$HE1 $HE1']") as "$". + iMod ("Hclose2" with "[$HE2 $HE2']") as "$". + done. + Qed. + + Lemma elctx_incl_dup E1 : + elctx_incl E1 (E1 ++ E1). + Proof. + iIntros (??) "#HE #HL * [HE1 HE1']". + iModIntro. iExists (qE1 / 2)%Qp. + rewrite /elctx_interp !big_sepL_app. iFrame. + iIntros "[HE1 HE1']". by iFrame. + Qed. + + Lemma elctx_sat_incl E1 E2 : + elctx_sat E1 [] E2 → elctx_incl E1 E2. + Proof. + iIntros (H12 ??) "#HE #HL * HE1". + iMod (H12 _ 1%Qp with "HE1 []") as (qE2) "[HE2 Hclose]". done. + { by rewrite /llctx_interp big_sepL_nil. } + iExists qE2. iFrame. iIntros "!> HE2". + by iMod ("Hclose" with "HE2") as "[$ _]". + Qed. + Lemma elctx_incl_lft_alive E1 E2 κ : lctx_lft_alive E1 [] κ → elctx_incl E1 E2 → elctx_incl E1 ((☀κ) :: E2). Proof. - iIntros (Hκ HE2 ??) "#HE #HL * [HE11 HE12]". - iMod (Hκ _ _ 1%Qp with "HE11 []") as (qE21) "[Hκ Hclose]". done. - { by rewrite /llctx_interp big_sepL_nil. } - iMod (HE2 with "HE HL * HE12") as (qE22) "[HE2 Hclose']". done. - destruct (Qp_lower_bound qE21 qE22) as (qE2 & ? & ? & -> & ->). - iExists qE2. rewrite /elctx_interp big_sepL_cons /=. - iDestruct "HE2" as "[$ HE2]". iDestruct "Hκ" as "[$ Hκ]". iIntros "!> [Hκ' HE2']". - iMod ("Hclose" with "[$Hκ $Hκ']") as "[$ _]". - iApply "Hclose'". by iFrame. + intros Hκ HE2. rewrite ->elctx_incl_dup. apply (elctx_incl_app _ [_]); last done. + apply elctx_sat_incl. apply elctx_sat_alive, elctx_sat_nil; first done. Qed. Lemma elctx_incl_lft_incl E1 E2 κ κ' : - lctx_lft_incl (E1 ++ E) L κ κ' → elctx_incl E1 E2 → + lctx_lft_incl (E ++ E1) L κ κ' → elctx_incl E1 E2 → elctx_incl E1 ((κ ⊑ κ') :: E2). Proof. iIntros (Hκκ' HE2 ??) "#HE #HL * HE1". @@ -356,14 +398,20 @@ Section elctx_incl. iIntros "!> [_ HE2']". by iApply "Hclose'". Qed. - Lemma elctx_sat_incl E1 E2 : - elctx_sat E1 [] E2 → elctx_incl E1 E2. + Lemma elctx_incl_lft_incl_alive E1 E2 κ κ' : + lctx_lft_incl (E ++ E1) L κ κ' → elctx_incl E1 E2 → + elctx_incl ((☀κ) :: E1) ((☀κ') :: E2). Proof. - iIntros (H12 ??) "#HE #HL * HE1". - iMod (H12 _ 1%Qp with "HE1 []") as (qE2) "[HE2 Hclose]". done. - { by rewrite /llctx_interp big_sepL_nil. } - iExists qE2. iFrame. iIntros "!> HE2". - by iMod ("Hclose" with "HE2") as "[$ _]". + intros Hκκ' HE2%(elctx_incl_lft_incl _ _ _ _ Hκκ'). + (* TODO: can we do this more in rewrite-style? *) + trans ((☀ κ) :: (κ ⊑ κ') :: E2)%EL. + { by apply (elctx_incl_app [_] [_]). } + apply (elctx_incl_app [_; _] [_]); last done. + (* TODO: Can we test the auto-context stuff here? *) + clear. apply elctx_sat_incl. apply elctx_sat_alive, elctx_sat_nil. + eapply lctx_lft_alive_external'. + - left. + - right. by apply elem_of_list_singleton. Qed. End elctx_incl. @@ -376,4 +424,4 @@ Hint Resolve elctx_incl_refl elctx_incl_nil elctx_incl_lft_alive elctx_incl_lft_incl : lrust_typing. -Hint Resolve lctx_lft_alive_external' | 100 : lrust_typing. \ No newline at end of file +Hint Resolve lctx_lft_alive_external' | 100 : lrust_typing. diff --git a/theories/typing/type.v b/theories/typing/type.v index ce6cdd10903b804fe65e8fcdfb1601c506b98a1e..18d51d634d883790b183ea97b5fd6279cef20e71 100644 --- a/theories/typing/type.v +++ b/theories/typing/type.v @@ -1,4 +1,5 @@ From iris.base_logic.lib Require Export na_invariants. +From iris.base_logic Require Import big_op. From lrust.lang Require Export proofmode notation. From lrust.lifetime Require Import borrow frac_borrow reborrow. From lrust.typing Require Import lft_contexts. @@ -428,6 +429,23 @@ Section subtyping. Qed. End subtyping. +Section weakening. + Context `{typeG Σ}. + + Lemma subtype_weaken E1 E2 L1 L2 ty1 ty2 : + E1 `contains` E2 → L1 `contains` L2 → + subtype E1 L1 ty1 ty2 → subtype E2 L2 ty1 ty2. + Proof. + (* TODO: There's no lemma relating `contains` to membership (∈)...?? *) + iIntros (HE12 [L' HL12]%contains_Permutation Hsub) "#LFT HE HL". + iApply (Hsub with "LFT [HE] [HL]"). + - rewrite /elctx_interp_0. by iApply big_sepL_contains. + - iDestruct "HL" as %HL. iPureIntro. intros ??. apply HL. + rewrite HL12. set_solver. + Qed. + +End weakening. + Hint Resolve subtype_refl eqtype_refl : lrust_typing. Ltac solve_typing := by eauto 100 with lrust_typing. diff --git a/theories/typing/type_context.v b/theories/typing/type_context.v index 258f75723f34324c18ee51a2324a35633c51bd2a..b9a465578b9bbe695659d0d9bef3ecefea5b7eb2 100644 --- a/theories/typing/type_context.v +++ b/theories/typing/type_context.v @@ -197,21 +197,20 @@ Section type_context. rewrite /tctx_incl. iIntros (Hc ???) "_ $ $ H". by iApply big_sepL_contains. Qed. - Lemma tctx_incl_frame E L T11 T12 T21 T22 : - tctx_incl E L T11 T12 → tctx_incl E L T21 T22 → - tctx_incl E L (T11++T21) (T12++T22). + Global Instance tctx_incl_app E L : + Proper (tctx_incl E L ==> tctx_incl E L ==> tctx_incl E L) app. Proof. - intros Hincl1 Hincl2 ???. rewrite /tctx_interp !big_sepL_app. + intros ?? Hincl1 ?? Hincl2 ???. rewrite /tctx_interp !big_sepL_app. iIntros "#LFT HE HL [H1 H2]". iMod (Hincl1 with "LFT HE HL H1") as "(HE & HL & $)". iApply (Hincl2 with "LFT HE HL H2"). Qed. Lemma tctx_incl_frame_l E L T T1 T2 : tctx_incl E L T1 T2 → tctx_incl E L (T++T1) (T++T2). - Proof. by apply tctx_incl_frame. Qed. + Proof. by apply tctx_incl_app. Qed. Lemma tctx_incl_frame_r E L T T1 T2 : tctx_incl E L T1 T2 → tctx_incl E L (T1++T) (T2++T). - Proof. by intros; apply tctx_incl_frame. Qed. + Proof. by intros; apply tctx_incl_app. Qed. Lemma copy_tctx_incl E L p `{!Copy ty} : tctx_incl E L [p ◠ty] [p ◠ty; p ◠ty].