From c8f3928306269dccff2aa230179a982155da4007 Mon Sep 17 00:00:00 2001 From: Ralf Jung <post@ralfj.de> Date: Wed, 21 Dec 2016 16:07:33 +0100 Subject: [PATCH] typed_instr and typed_body need the heap_ctx; prove assignment (based on typed_writing) --- theories/typing/bool.v | 8 +++--- theories/typing/cont.v | 8 +++--- theories/typing/function.v | 22 ++++++++-------- theories/typing/int.v | 8 +++--- theories/typing/own.v | 2 +- theories/typing/programs.v | 48 +++++++++++++++++++++++++--------- theories/typing/type_context.v | 8 ++++++ 7 files changed, 67 insertions(+), 37 deletions(-) diff --git a/theories/typing/bool.v b/theories/typing/bool.v index 4230b62c..f8b6c3f1 100644 --- a/theories/typing/bool.v +++ b/theories/typing/bool.v @@ -19,7 +19,7 @@ Section typing. Lemma type_bool (b : Datatypes.bool) E L : typed_instruction_ty E L [] #b bool. Proof. - iIntros (tid qE) "!# _ $ $ _". wp_value. rewrite tctx_interp_singleton. + iIntros (tid qE) "_ _ $ $ _". wp_value. rewrite tctx_interp_singleton. iExists _. iSplitR; first done. iExists _. done. Qed. @@ -28,12 +28,12 @@ Section typing. typed_body E L C (TCtx_hasty p bool :: T) (if: p then e1 else e2). Proof. (* FIXME why can't I merge these two iIntros? *) - iIntros (He1 He2). iIntros (tid qE) "#LFT HE HL HC". + iIntros (He1 He2). iIntros (tid qE) "#HEAP #LFT HE HL HC". rewrite tctx_interp_cons. iIntros "[Hp HT]". wp_bind p. iApply (wp_hasty with "Hp"). iIntros (v) "_ Hown". iDestruct "Hown" as (b) "Hv". iDestruct "Hv" as %[=->]. destruct b; wp_if. - - iApply (He1 with "LFT HE HL HC HT"). - - iApply (He2 with "LFT HE HL HC HT"). + - iApply (He1 with "HEAP LFT HE HL HC HT"). + - iApply (He2 with "HEAP LFT HE HL HC HT"). Qed. End typing. diff --git a/theories/typing/cont.v b/theories/typing/cont.v index be7f6344..4189b543 100644 --- a/theories/typing/cont.v +++ b/theories/typing/cont.v @@ -12,7 +12,7 @@ Section typing. tctx_incl E L T (T' args) → typed_body E L [CCtx_iscont k L n T'] T (k (of_val <$> (args : list _))). Proof. - iIntros (Hincl tid qE) "#LFT HE HL HC HT". + iIntros (Hincl tid qE) "#HEAP #LFT HE HL HC HT". iMod (Hincl with "LFT HE HL HT") as "(HE & HL & HT)". iSpecialize ("HC" with "HE * []"); first by (iPureIntro; apply elem_of_list_singleton). simpl. iApply ("HC" with "* HL HT"). @@ -25,16 +25,16 @@ Section typing. (∀ k, typed_body E (L1 ++ L2) (CCtx_iscont k L1 n T' :: C) T (subst' kb k e2)) → typed_body E (L1 ++ L2) C T (let: kb := e1 in e2). Proof. - iIntros (-> Hc1 Hc2 Hecont He2 tid qE) "#LFT HE HL HC HT". iApply wp_let'. + iIntros (-> Hc1 Hc2 Hecont He2 tid qE) "#HEAP #LFT HE HL HC HT". iApply wp_let'. { simpl. rewrite decide_left. done. } - iModIntro. iApply (He2 with "* LFT HE HL [HC] HT"). clear He2. + iModIntro. iApply (He2 with "* HEAP LFT HE HL [HC] HT"). clear He2. iIntros "HE". iLöb as "IH". iIntros (x) "H". iDestruct "H" as %[->|?]%elem_of_cons; last by iApply ("HC" with "HE *"). iIntros (args) "HL HT". iApply wp_rec; try done. { apply Forall_of_val_is_val. } { rewrite -vec_to_list_map -subst_vec_eq. eauto. } (* FIXME: iNext here unfolds things in the context. *) - iNext. iApply (Hecont with "* LFT HE HL [HC] HT"). + iNext. iApply (Hecont with "* HEAP LFT HE HL [HC] HT"). by iApply "IH". Qed. diff --git a/theories/typing/function.v b/theories/typing/function.v index 44f8af54..7255a4e5 100644 --- a/theories/typing/function.v +++ b/theories/typing/function.v @@ -32,9 +32,9 @@ Section typing. Proof. intros Htys Hty. apply subtype_simple_type=>//= _ vl. iIntros "#LFT #HE0 #HL0 Hf". iDestruct "Hf" as (f) "[% #Hf]". subst. - iExists f. iSplit. done. rewrite /typed_body. iIntros "!# * _ HE HL HC HT". + iExists f. iSplit. done. rewrite /typed_body. iIntros "!# * #HEAP _ HE HL HC HT". iDestruct (elctx_interp_persist with "HE") as "#HE'". - iApply ("Hf" with "* LFT HE HL [HC] [HT]"). + iApply ("Hf" with "* HEAP LFT HE HL [HC] [HT]"). - iIntros "HE". unfold cctx_interp. iIntros (e) "He". iDestruct "He" as %->%elem_of_list_singleton. iIntros (ret) "HL HT". iSpecialize ("HC" with "HE"). unfold cctx_elt_interp. @@ -75,9 +75,9 @@ Section typing. Proof. intros HEE'. apply subtype_simple_type=>//= _ vl. iIntros "#LFT _ _ Hf". iDestruct "Hf" as (f) "[% #Hf]". subst. - iExists f. iSplit. done. rewrite /typed_body. iIntros "!# * _ HE #HL HC HT". + iExists f. iSplit. done. rewrite /typed_body. iIntros "!# * #HEAP _ HE #HL HC HT". iMod (HEE' x with "[%] HE HL") as (qE') "[HE Hclose]". done. - iApply ("Hf" with "* LFT HE HL [Hclose HC] HT"). iIntros "HE". + iApply ("Hf" with "* HEAP LFT HE HL [Hclose HC] HT"). iIntros "HE". iApply fupd_cctx_interp. iApply ("HC" with ">"). by iMod ("Hclose" with "HE") as "[$ _]". Qed. @@ -88,8 +88,8 @@ Section typing. Proof. intros Hκκ'. apply subtype_simple_type=>//= _ vl. iIntros "#LFT #HE0 #HL0 Hf". iDestruct "Hf" as (f) "[% #Hf]". subst. - iExists f. iSplit. done. rewrite /typed_body. iIntros "!# * _ HE #HL HC HT". - iApply ("Hf" with "* LFT [HE] HL [HC] HT"). + iExists f. iSplit. done. rewrite /typed_body. iIntros "!# * #HEAP _ HE #HL HC HT". + iApply ("Hf" with "* HEAP LFT [HE] HL [HC] HT"). { rewrite /elctx_interp big_sepL_cons. iFrame. iApply (Hκκ' with "HE0 HL0"). } rewrite /elctx_interp big_sepL_cons. iIntros "[_ HE]". by iApply "HC". Qed. @@ -100,7 +100,7 @@ Section typing. typed_body E L [CCtx_iscont k L 1 (λ v, (TCtx_hasty (v!!!0) (ty x)) :: T')] (TCtx_hasty p (fn E' tys ty) :: T) (p (of_val k :: ps)). Proof. - iIntros (HTsat HEsat tid qE) "#LFT HE HL HC". + iIntros (HTsat HEsat tid qE) "#HEAP #LFT HE HL HC". rewrite tctx_interp_cons. iIntros "[Hf HT]". wp_bind p. iApply (wp_hasty with "Hf"). iIntros (v) "% Hf". iMod (HTsat with "LFT HE HL HT") as "(HE & HL & HT)". rewrite tctx_interp_app. @@ -126,7 +126,7 @@ Section typing. iDestruct "Hf" as (f) "[EQ #Hf]". iDestruct "EQ" as %[=->]. iSpecialize ("Hf" $! x vl k). iMod (HEsat with "[%] HE HL") as (q') "[HE' Hclose]"; first done. - iApply ("Hf" with "LFT HE' [] [HC Hclose HT']"). + iApply ("Hf" with "HEAP LFT HE' [] [HC Hclose HT']"). + by rewrite /llctx_interp big_sepL_nil. + iIntros "HE'". iApply fupd_cctx_interp. iMod ("Hclose" with "HE'") as "[HE HL]". iSpecialize ("HC" with "HE"). iModIntro. iIntros (y) "IN". @@ -147,16 +147,16 @@ Section typing. (subst' fb f $ subst_vec (kb ::: argsb) (Vector.map of_val $ k ::: args) e)) → typed_instruction_ty E L (zip_with TCtx_hasty cps ctyl) ef (fn E' tys ty). Proof. - iIntros (-> Hc Hbody tid qE) "!# #LFT $ $ #HT". iApply wp_value. + iIntros (-> Hc Hbody tid qE) "#HEAP #LFT $ $ #HT". iApply wp_value. { simpl. rewrite decide_left. done. } rewrite tctx_interp_singleton. iLöb as "IH". iExists _. iSplit. { simpl. rewrite decide_left. done. } iExists _. iSplit; first done. iAlways. clear qE. - iIntros (x args k). iIntros (tid' qE) "_ HE HL HC HT'". + iIntros (x args k). iIntros (tid' qE) "_ _ HE HL HC HT'". iApply wp_rec; try done. { apply Forall_of_val_is_val. } { rewrite -!vec_to_list_cons -vec_to_list_map -subst_vec_eq. eauto. } - iApply (Hbody with "* LFT HE HL HC"). + iApply (Hbody with "* HEAP LFT HE HL HC"). rewrite tctx_interp_cons tctx_interp_app. iFrame "HT' IH". iApply tctx_send. by iNext. Qed. diff --git a/theories/typing/int.v b/theories/typing/int.v index 835cfda1..eb59fd32 100644 --- a/theories/typing/int.v +++ b/theories/typing/int.v @@ -19,14 +19,14 @@ Section typing. Lemma type_int (z : Z) E L : typed_instruction_ty E L [] #z int. Proof. - iIntros (tid qE) "!# _ $ $ _". wp_value. rewrite tctx_interp_singleton. + iIntros (tid qE) "_ _ $ $ _". wp_value. rewrite tctx_interp_singleton. iExists _. iSplitR; first done. iExists _. done. Qed. Lemma type_plus E L p1 p2 : typed_instruction_ty E L [TCtx_hasty p1 int; TCtx_hasty p2 int] (p1 + p2) int. Proof. - iIntros (tid qE) "!# _ $ $". rewrite tctx_interp_cons tctx_interp_singleton. + iIntros (tid qE) "_ _ $ $". rewrite tctx_interp_cons tctx_interp_singleton. iIntros "[Hp1 Hp2]". wp_bind p1. iApply (wp_hasty with "Hp1"). iIntros (v1) "_ Hown1". wp_bind p2. iApply (wp_hasty with "Hp2"). iIntros (v2) "_ Hown2". @@ -39,7 +39,7 @@ Section typing. Lemma type_minus E L p1 p2 : typed_instruction_ty E L [TCtx_hasty p1 int; TCtx_hasty p2 int] (p1 - p2) int. Proof. - iIntros (tid qE) "!# _ $ $". rewrite tctx_interp_cons tctx_interp_singleton. + iIntros (tid qE) "_ _ $ $". rewrite tctx_interp_cons tctx_interp_singleton. iIntros "[Hp1 Hp2]". wp_bind p1. iApply (wp_hasty with "Hp1"). iIntros (v1) "_ Hown1". wp_bind p2. iApply (wp_hasty with "Hp2"). iIntros (v2) "_ Hown2". @@ -52,7 +52,7 @@ Section typing. Lemma type_le E L p1 p2 : typed_instruction_ty E L [TCtx_hasty p1 int; TCtx_hasty p2 int] (p1 ≤ p2) bool. Proof. - iIntros (tid qE) "!# _ $ $". rewrite tctx_interp_cons tctx_interp_singleton. + iIntros (tid qE) "_ _ $ $". rewrite tctx_interp_cons tctx_interp_singleton. iIntros "[Hp1 Hp2]". wp_bind p1. iApply (wp_hasty with "Hp1"). iIntros (v1) "_ Hown1". wp_bind p2. iApply (wp_hasty with "Hp2"). iIntros (v2) "_ Hown2". diff --git a/theories/typing/own.v b/theories/typing/own.v index 9ca354dd..78138e0b 100644 --- a/theories/typing/own.v +++ b/theories/typing/own.v @@ -142,7 +142,7 @@ Section typing. Lemma write_own E L ty ty' n : ty.(ty_size) = ty'.(ty_size) → typed_writing E L (own n ty') ty (own n ty). Proof. - iIntros (Hsz p tid F ?) "_ Hown". iDestruct "Hown" as (l) "(Heq & H↦ & H†)". + iIntros (Hsz p tid F qE qL ?) "_ $ $ Hown". iDestruct "Hown" as (l) "(Heq & H↦ & H†)". iDestruct "Heq" as %[= ->]. iDestruct "H↦" as (vl) "[>H↦ Hown]". rewrite ty'.(ty_size_eq). (* This turns out to be the fastest way to apply a lemma below â–· -- at least if we're fine throwing away the premise even though the result is persistent, which in this case, we are. *) iDestruct "Hown" as ">%". iModIntro. iExists _, _. iFrame "H↦". diff --git a/theories/typing/programs.v b/theories/typing/programs.v index 0b5ae8ba..0479a702 100644 --- a/theories/typing/programs.v +++ b/theories/typing/programs.v @@ -8,9 +8,10 @@ Section typing. Context `{typeG Σ}. (** Function Body *) + (* This is an iProp because it is also used by the function type. *) Definition typed_body (E : elctx) (L : llctx) (C : cctx) (T : tctx) (e : expr) : iProp Σ := - (∀ tid qE, lft_ctx -∗ elctx_interp E qE -∗ llctx_interp L 1 -∗ + (∀ tid qE, heap_ctx -∗ lft_ctx -∗ elctx_interp E qE -∗ llctx_interp L 1 -∗ (elctx_interp E qE -∗ cctx_interp tid C) -∗ tctx_interp tid T -∗ WP e {{ _, cont_postcondition }})%I. Global Arguments typed_body _ _ _ _ _%E. @@ -31,25 +32,26 @@ Section typing. Proper (flip (cctx_incl E) ==> flip (tctx_incl E L) ==> eq ==> (⊢)) (typed_body E L). Proof. intros C1 C2 HC T1 T2 HT e ? <-. iIntros "H". - iIntros (tid qE) "#LFT HE HL HC HT". + iIntros (tid qE) "#HEAP #LFT HE HL HC HT". iMod (HT with "LFT HE HL HT") as "(HE & HL & HT)". - iApply ("H" with "LFT HE HL [HC] HT"). + iApply ("H" with "HEAP LFT HE HL [HC] HT"). iIntros "HE". by iApply (HC with "LFT HC"). Qed. (** Instruction *) Definition typed_instruction (E : elctx) (L : llctx) - (T1 : tctx) (e : expr) (T2 : val → tctx) : iProp Σ := - (∀ tid qE, â–¡ (lft_ctx -∗ elctx_interp E qE -∗ llctx_interp L 1 -∗ tctx_interp tid T1 -∗ - WP e {{ v, elctx_interp E qE ∗ llctx_interp L 1 ∗ tctx_interp tid (T2 v) }}))%I. + (T1 : tctx) (e : expr) (T2 : val → tctx) : Prop := + ∀ tid qE, heap_ctx -∗ lft_ctx -∗ elctx_interp E qE -∗ llctx_interp L 1 -∗ tctx_interp tid T1 -∗ + WP e {{ v, elctx_interp E qE ∗ llctx_interp L 1 ∗ tctx_interp tid (T2 v) }}. Global Arguments typed_instruction _ _ _ _%E _. (** Writing and Reading **) Definition typed_writing (E : elctx) (L : llctx) (ty1 ty ty2 : type) : Prop := - ∀ v tid E, lftE ∪ (↑lrustN) ⊆ E → - lft_ctx -∗ ty1.(ty_own) tid [v] ={E}=∗ - ∃ l vl, ⌜length vl = ty.(ty_size)⌠∗ l ↦∗ vl ∗ - ∀ vl', l ↦∗ vl' -∗ â–· (ty.(ty_own) tid vl') ={E}=∗ ty2.(ty_own) tid [v]. + ∀ v tid F qE qL, lftE ∪ (↑lrustN) ⊆ F → + lft_ctx -∗ elctx_interp E qE -∗ llctx_interp L qL -∗ ty1.(ty_own) tid [v] ={F}=∗ + ∃ (l : loc) vl, ⌜length vl = ty.(ty_size) ∧ v = #l⌠∗ l ↦∗ vl ∗ + ∀ vl', l ↦∗ vl' -∗ (ty.(ty_own) tid vl') ={F}=∗ + elctx_interp E qE ∗ llctx_interp L qL ∗ ty2.(ty_own) tid [v]. End typing. Notation typed_instruction_ty E L T1 e ty := (typed_instruction E L T1 e (λ v : val, [TCtx_hasty v ty])). @@ -63,10 +65,30 @@ Section typing_rules. (∀ v : val, typed_body E L C (T2 v ++ T) (subst' xb v e')) → typed_body E L C (T1 ++ T) (let: xb := e in e'). Proof. - iIntros (Hc He He' tid qE) "#LFT HE HL HC HT". rewrite tctx_interp_app. + iIntros (Hc He He' tid qE) "#HEAP #LFT HE HL HC HT". rewrite tctx_interp_app. iDestruct "HT" as "[HT1 HT]". wp_bind e. iApply (wp_wand with "[HE HL HT1]"). - { iApply (He with "LFT HE HL HT1"). } + { iApply (He with "HEAP LFT HE HL HT1"). } iIntros (v) "/= (HE & HL & HT2)". iApply wp_let; first wp_done. iModIntro. - iApply (He' with "LFT HE HL HC [HT2 HT]"). rewrite tctx_interp_app. by iFrame. + iApply (He' with "HEAP LFT HE HL HC [HT2 HT]"). rewrite tctx_interp_app. by iFrame. Qed. + + Lemma type_assign E L ty1 ty ty1' p1 p2 : + typed_writing E L ty1 ty ty1' → + typed_instruction E L [TCtx_hasty p1 ty1; TCtx_hasty p2 ty] (p1 <- p2) + (λ _, [TCtx_hasty p1 ty1']). + Proof. + iIntros (Hwrt tid qE) "#HEAP #LFT HE HL". + rewrite tctx_interp_cons tctx_interp_singleton. iIntros "[Hp1 Hp2]". + wp_bind p1. iApply (wp_hasty with "Hp1"). iIntros (v1) "% Hown1". + wp_bind p2. iApply (wp_hasty with "Hp2"). iIntros (v2) "_ Hown2". + iMod (Hwrt with "* LFT HE HL Hown1") as (l vl) "([% %] & Hl & Hclose)"; first done. + subst v1. iAssert (⌜1%nat = ty_size tyâŒ%I) with "[#]" as %Hsz. + { change (1%nat) with (length [v2]). by iApply ty_size_eq. } + rewrite <-Hsz in *. destruct vl as [|v[|]]; try done. + rewrite heap_mapsto_vec_singleton. wp_write. + rewrite -heap_mapsto_vec_singleton. + iMod ("Hclose" with "* Hl Hown2") as "($ & $ & Hown)". + rewrite tctx_interp_singleton tctx_hasty_val' //. + Qed. + End typing_rules. diff --git a/theories/typing/type_context.v b/theories/typing/type_context.v index 7fb79ab5..0bac33bd 100644 --- a/theories/typing/type_context.v +++ b/theories/typing/type_context.v @@ -72,6 +72,14 @@ Section type_context. tctx_elt_interp tid (TCtx_hasty p2 ty). Proof. intros Hp. rewrite /tctx_elt_interp /=. setoid_rewrite Hp. done. Qed. + Lemma tctx_hasty_val' tid p (v : val) ty : + eval_path p = Some v → + tctx_elt_interp tid (TCtx_hasty p ty) ⊣⊢ ty.(ty_own) tid [v]. + Proof. + intros ?. rewrite -tctx_hasty_val. apply tctx_elt_interp_hasty_path. + rewrite eval_path_of_val. done. + Qed. + Lemma wp_hasty E tid p ty Φ : tctx_elt_interp tid (TCtx_hasty p ty) -∗ (∀ v, ⌜eval_path p = Some v⌠-∗ ty.(ty_own) tid [v] -∗ Φ v) -∗ -- GitLab