diff --git a/_CoqProject b/_CoqProject index 50b5c06cdde2b32c4b5735d1cea1f077f881eed5..3bd069d9470d6943ac46dda8fe788ca9f0808f6a 100644 --- a/_CoqProject +++ b/_CoqProject @@ -30,6 +30,7 @@ theories/typing/types.v theories/typing/interp.v theories/typing/fundamental.v theories/typing/contextual_refinement.v +theories/typing/tactics.v theories/typing/soundness.v theories/reloc.v diff --git a/theories/examples/or.v b/theories/examples/or.v index a794d2abd5e0a938cf1550ccede01f6c654df1f6..5ce043a9366f6a899aa865e22120d6f550d5e1e0 100644 --- a/theories/examples/or.v +++ b/theories/examples/or.v @@ -288,4 +288,75 @@ Section rules. End rules. -(* TODO: write out the contextual refinements *) + +(** Separately, we prove that the ordering induced by ⊕ conincides with + contextual refinement. *) +Lemma Seq_typed Γ e1 e2 τ : + Γ ⊢ₜ e1 : TUnit → + Γ ⊢ₜ e2 : τ → + Γ ⊢ₜ (e1;;e2) : τ. +Proof. by repeat (econstructor; eauto). Qed. + +Lemma or_equiv_refines_1 e t : + (∅ ⊢ₜ e : TUnit) → + (∅ ⊢ₜ t : TUnit) → + (∅ ⊨ e ≤ctx≤ t : TUnit) → + (∅ ⊨ (e ⊕ t) =ctx= t : TUnit). +Proof. + intros Te Tt Het. split; last first. + - eapply (ctx_refines_transitive _ _ _ (t ⊕ e)%V). + + eapply (refines_sound relocΣ). + iIntros (? Δ). + iApply (or_choice_1_r t t with "[]"). + by iApply refines_typed. + + eapply (refines_sound relocΣ). + iIntros (? Δ). rel_pures_r. + iApply or_comm; by iApply (refines_typed TUnit []). + - eapply (ctx_refines_transitive _ _ _ (t ⊕ t)%E). + + ctx_bind_l e. + ctx_bind_r t. + eapply (ctx_refines_congruence ∅ _ _ TUnit); + last eassumption. + { cbn. + econstructor; cbn; eauto. + - econstructor; cbn; eauto. + econstructor; cbn; eauto. + - econstructor; cbn; eauto. + + econstructor; cbn; eauto. + econstructor; cbn; eauto. + econstructor; cbn; eauto. + change Z0 with (Z.of_nat 0%nat). + econstructor; cbn; eauto. + econstructor; cbn; eauto. + * econstructor; cbn; eauto. + eapply Seq_typed. + ** change 1%Z with (Z.of_nat 1%nat). + repeat (econstructor; cbn; eauto). + ** repeat (econstructor; cbn; eauto). + * repeat (econstructor; cbn; eauto). + + econstructor; cbn; eauto. + 2:{ econstructor; cbn; eauto. } + enough (typed_ctx_item (CTX_Rec <> <>) + (binder_insert BAnon (TUnit → TUnit)%ty + (binder_insert BAnon TUnit (∅ : stringmap type))) + TUnit ∅ (TUnit → TUnit)). + { by simpl in *. } + eapply (TP_CTX_Rec ∅ TUnit TUnit BAnon BAnon). } + + eapply (refines_sound relocΣ). + iIntros (? Δ). rel_pures_l. + iApply or_idemp_l. by iApply (refines_typed TUnit []). +Qed. + +Lemma or_equiv_refines_2 e t : + (∅ ⊢ₜ e : TUnit) → + (∅ ⊢ₜ t : TUnit) → + (∅ ⊨ (e ⊕ t) =ctx= t : TUnit) → + (∅ ⊨ e ≤ctx≤ t : TUnit). +Proof. + intros Te Tt [Het1 Het2]. + eapply (ctx_refines_transitive _ _ _ (e ⊕ t)%E); last assumption. + eapply (refines_sound relocΣ). + iIntros (? Δ). + rel_pures_r. iApply or_choice_1_r. + by iApply (refines_typed TUnit []). +Qed. diff --git a/theories/reloc.v b/theories/reloc.v index 9e4e1d3c796b590fa0204cd3d9b857958ac19edc..fed94d6ead0f73cfecc3d8ae4d0112ce954f3738 100644 --- a/theories/reloc.v +++ b/theories/reloc.v @@ -2,4 +2,4 @@ From iris.heap_lang Require Export lang notation proofmode. From iris.proofmode Require Export tactics. From reloc.logic Require Export proofmode.tactics proofmode.spec_tactics model. From reloc.logic Require Export rules derived compatibility. -From reloc.typing Require Export interp soundness. +From reloc.typing Require Export interp tactics soundness. diff --git a/theories/typing/contextual_refinement.v b/theories/typing/contextual_refinement.v index c12db48cae684d62a290cb71b4168d6812027a18..74c7248b207387bdcca2c13888a4026033f85986 100644 --- a/theories/typing/contextual_refinement.v +++ b/theories/typing/contextual_refinement.v @@ -6,14 +6,14 @@ From iris.proofmode Require Import tactics. From reloc.typing Require Export types interp fundamental. Inductive ctx_item := - (* λ-rec *) - | CTX_Rec (f x: binder) + (* Base lambda calculus *) + | CTX_Rec (f x : binder) | CTX_AppL (e2 : expr) | CTX_AppR (e1 : expr) - (* Bin op *) + (* Base types and their operations *) + | CTX_UnOp (op : un_op) | CTX_BinOpL (op : bin_op) (e2 : expr) | CTX_BinOpR (op : bin_op) (e1 : expr) - (* If *) | CTX_IfL (e1 : expr) (e2 : expr) | CTX_IfM (e0 : expr) (e2 : expr) | CTX_IfR (e0 : expr) (e1 : expr) @@ -28,6 +28,19 @@ Inductive ctx_item := | CTX_CaseL (e1 : expr) (e2 : expr) | CTX_CaseM (e0 : expr) (e2 : expr) | CTX_CaseR (e0 : expr) (e1 : expr) + (* Concurrency *) + | CTX_Fork + (* Heap *) + | CTX_Alloc + | CTX_Load + | CTX_StoreL (e2 : expr) + | CTX_StoreR (e1 : expr) + (* Compare-exchange and FAA *) + | CTX_CmpXchgL (e1 : expr) (e2 : expr) + | CTX_CmpXchgM (e0 : expr) (e2 : expr) + | CTX_CmpXchgR (e0 : expr) (e1 : expr) + | CTX_FAAL (e1 : expr) + | CTX_FAAR (e0 : expr) (* Recursive Types *) | CTX_Fold | CTX_Unfold @@ -35,55 +48,54 @@ Inductive ctx_item := | CTX_TLam | CTX_TApp (* Existential types *) - (* | CTX_Pack *) - (* | CTX_UnpackL (e' : expr) *) - (* | CTX_UnpackR (e : expr) *) - (* Concurrency *) - | CTX_Fork - (* Reference Types *) - | CTX_Alloc - | CTX_Load - | CTX_StoreL (e2 : expr) - | CTX_StoreR (e1 : expr) - (* Compare-exchange used for fine-grained concurrency *) - | CTX_CmpXchg_L (e1 : expr) (e2 : expr) - | CTX_CmpXchg_M (e0 : expr) (e2 : expr) - | CTX_CmpXchg_R (e0 : expr) (e1 : expr). + (* Nb: we do not have an explicit PACK operation *) + | CTX_UnpackL (x : binder) (e2 : expr) + | CTX_UnpackR (x : binder) (e1 : expr) +. Fixpoint fill_ctx_item (ctx : ctx_item) (e : expr) : expr := match ctx with + (* Base lambda calculus *) | CTX_Rec f x => Rec f x e | CTX_AppL e2 => App e e2 | CTX_AppR e1 => App e1 e + (* Base types and operations *) + | CTX_UnOp op => UnOp op e + | CTX_BinOpL op e2 => BinOp op e e2 + | CTX_BinOpR op e1 => BinOp op e1 e + | CTX_IfL e1 e2 => If e e1 e2 + | CTX_IfM e0 e2 => If e0 e e2 + | CTX_IfR e0 e1 => If e0 e1 e + (* Products *) | CTX_PairL e2 => Pair e e2 | CTX_PairR e1 => Pair e1 e | CTX_Fst => Fst e | CTX_Snd => Snd e + (* Sums *) | CTX_InjL => InjL e | CTX_InjR => InjR e | CTX_CaseL e1 e2 => Case e e1 e2 | CTX_CaseM e0 e2 => Case e0 e e2 | CTX_CaseR e0 e1 => Case e0 e1 e - | CTX_BinOpL op e2 => BinOp op e e2 - | CTX_BinOpR op e1 => BinOp op e1 e - | CTX_IfL e1 e2 => If e e1 e2 - | CTX_IfM e0 e2 => If e0 e e2 - | CTX_IfR e0 e1 => If e0 e1 e - | CTX_Fold => e - | CTX_Unfold => rec_unfold e - | CTX_TLam => Λ: e - | CTX_TApp => TApp e - (* | CTX_Pack => Pack e *) - (* | CTX_UnpackL e1 => Unpack e e1 *) - (* | CTX_UnpackR e0 => Unpack e0 e *) + (* Concurrency *) | CTX_Fork => Fork e + (* Heap & atomic CAS/FAA *) | CTX_Alloc => Alloc e | CTX_Load => Load e | CTX_StoreL e2 => Store e e2 | CTX_StoreR e1 => Store e1 e - | CTX_CmpXchg_L e1 e2 => CmpXchg e e1 e2 - | CTX_CmpXchg_M e0 e2 => CmpXchg e0 e e2 - | CTX_CmpXchg_R e0 e1 => CmpXchg e0 e1 e + | CTX_CmpXchgL e1 e2 => CmpXchg e e1 e2 + | CTX_CmpXchgM e0 e2 => CmpXchg e0 e e2 + | CTX_CmpXchgR e0 e1 => CmpXchg e0 e1 e + | CTX_FAAL e1 => FAA e e1 + | CTX_FAAR e0 => FAA e0 e + (* Recursive & polymorphic types *) + | CTX_Fold => e + | CTX_Unfold => rec_unfold e + | CTX_TLam => Λ: e + | CTX_TApp => TApp e + | CTX_UnpackL x e1 => unpack: x:=e in e1 + | CTX_UnpackR x e0 => unpack: x:=e0 in e end. Definition ctx := list ctx_item. @@ -94,6 +106,7 @@ Definition fill_ctx (K : ctx) (e : expr) : expr := foldr fill_ctx_item e K. (** typed ctx *) Inductive typed_ctx_item : ctx_item → stringmap type → type → stringmap type → type → Prop := + (* Base lambda calculus *) | TP_CTX_Rec Γ τ τ' f x : typed_ctx_item (CTX_Rec f x) (<[f:=TArrow τ τ']>(<[x:=τ]>Γ)) τ' Γ (TArrow τ τ') | TP_CTX_AppL Γ e2 τ τ' : @@ -102,6 +115,33 @@ Inductive typed_ctx_item : | TP_CTX_AppR Γ e1 τ τ' : typed Γ e1 (TArrow τ τ') → typed_ctx_item (CTX_AppR e1) Γ τ Γ τ' + (* Base types and operations *) + | TP_CTX_BinOpL_Nat op Γ e2 τ : + typed Γ e2 TNat → + binop_nat_res_type op = Some τ → + typed_ctx_item (CTX_BinOpL op e2) Γ TNat Γ τ + | TP_CTX_BinOpR_Nat op e1 Γ τ : + typed Γ e1 TNat → + binop_nat_res_type op = Some τ → + typed_ctx_item (CTX_BinOpR op e1) Γ TNat Γ τ + | TP_CTX_BinOpL_Bool op Γ e2 τ : + typed Γ e2 TBool → + binop_bool_res_type op = Some τ → + typed_ctx_item (CTX_BinOpL op e2) Γ TBool Γ τ + | TP_CTX_BinOpR_Bool op e1 Γ τ : + typed Γ e1 TBool → + binop_bool_res_type op = Some τ → + typed_ctx_item (CTX_BinOpR op e1) Γ TBool Γ τ + | TP_CTX_IfL Γ e1 e2 τ : + typed Γ e1 τ → typed Γ e2 τ → + typed_ctx_item (CTX_IfL e1 e2) Γ (TBool) Γ τ + | TP_CTX_IfM Γ e0 e2 τ : + typed Γ e0 (TBool) → typed Γ e2 τ → + typed_ctx_item (CTX_IfM e0 e2) Γ τ Γ τ + | TP_CTX_IfR Γ e0 e1 τ : + typed Γ e0 (TBool) → typed Γ e1 τ → + typed_ctx_item (CTX_IfR e0 e1) Γ τ Γ τ + (* Products *) | TP_CTX_PairL Γ e2 τ τ' : typed Γ e2 τ' → typed_ctx_item (CTX_PairL e2) Γ τ Γ (TProd τ τ') @@ -112,6 +152,7 @@ Inductive typed_ctx_item : typed_ctx_item CTX_Fst Γ (TProd τ τ') Γ τ | TP_CTX_Snd Γ τ τ' : typed_ctx_item CTX_Snd Γ (TProd τ τ') Γ τ' + (* Sums *) | TP_CTX_InjL Γ τ τ' : typed_ctx_item CTX_InjL Γ τ Γ (TSum τ τ') | TP_CTX_InjR Γ τ τ' : @@ -125,49 +166,10 @@ Inductive typed_ctx_item : | TP_CTX_CaseR Γ e0 e1 τ1 τ2 τ' : typed Γ e0 (TSum τ1 τ2) → typed Γ e1 (TArrow τ1 τ') → typed_ctx_item (CTX_CaseR e0 e1) Γ (TArrow τ2 τ') Γ τ' - | TP_CTX_IfL Γ e1 e2 τ : - typed Γ e1 τ → typed Γ e2 τ → - typed_ctx_item (CTX_IfL e1 e2) Γ (TBool) Γ τ - | TP_CTX_IfM Γ e0 e2 τ : - typed Γ e0 (TBool) → typed Γ e2 τ → - typed_ctx_item (CTX_IfM e0 e2) Γ τ Γ τ - | TP_CTX_IfR Γ e0 e1 τ : - typed Γ e0 (TBool) → typed Γ e1 τ → - typed_ctx_item (CTX_IfR e0 e1) Γ τ Γ τ - | TP_CTX_BinOpL_Nat op Γ e2 τ : - typed Γ e2 TNat → - binop_nat_res_type op = Some τ → - typed_ctx_item (CTX_BinOpL op e2) Γ TNat Γ τ - | TP_CTX_BinOpR_Nat op e1 Γ τ : - typed Γ e1 TNat → - binop_nat_res_type op = Some τ → - typed_ctx_item (CTX_BinOpR op e1) Γ TNat Γ τ - | TP_CTX_BinOpL_Bool op Γ e2 τ : - typed Γ e2 TBool → - binop_bool_res_type op = Some τ → - typed_ctx_item (CTX_BinOpL op e2) Γ TBool Γ τ - | TP_CTX_BinOpR_Bool op e1 Γ τ : - typed Γ e1 TBool → - binop_bool_res_type op = Some τ → - typed_ctx_item (CTX_BinOpR op e1) Γ TBool Γ τ - | TP_CTX_Fold Γ τ : - typed_ctx_item CTX_Fold Γ τ.[(TRec τ)/] Γ (TRec τ) - | TP_CTX_Unfold Γ τ : - typed_ctx_item CTX_Unfold Γ (TRec τ) Γ τ.[(TRec τ)/] - | TP_CTX_TLam Γ τ : - typed_ctx_item CTX_TLam (Autosubst_Classes.subst (ren (+1%nat)) <$> Γ) τ Γ (TForall τ) - | TP_CTX_TApp Γ τ τ' : - typed_ctx_item CTX_TApp Γ (TForall τ) Γ τ.[τ'/] - (* | TP_CTX_Pack Γ τ τ' : *) - (* typed_ctx_item CTX_Pack Γ τ.[τ'/] Γ (TExists τ) *) - (* | TP_CTX_UnpackL e2 Γ τ τ2 : *) - (* typed (subst (ren (+1)) <$> Γ) e2 (TArrow τ (subst (ren (+1)) τ2)) → *) - (* typed_ctx_item (CTX_UnpackL e2) Γ (TExists τ) Γ τ2 *) - (* | TP_CTX_UnpackR e1 Γ τ τ2 : *) - (* typed Γ e1 (TExists τ) → *) - (* typed_ctx_item (CTX_UnpackR e1) (subst (ren (+1)) <$> Γ) (TArrow τ (subst (ren (+1)) τ2)) Γ τ2 *) + (* Concurrency *) | TP_CTX_Fork Γ : typed_ctx_item CTX_Fork Γ TUnit Γ TUnit + (* Heap *) | TPCTX_Alloc Γ τ : typed_ctx_item CTX_Alloc Γ τ Γ (Tref τ) | TP_CTX_Load Γ τ : @@ -177,18 +179,44 @@ Inductive typed_ctx_item : | TP_CTX_StoreR Γ e1 τ : typed Γ e1 (Tref τ) → typed_ctx_item (CTX_StoreR e1) Γ τ Γ TUnit - | TP_CTX_CasL Γ e1 e2 τ : + | TP_CTX_FAAL Γ e2 : + Γ ⊢ₜ e2 : TNat → + typed_ctx_item (CTX_FAAL e2) Γ (Tref TNat) Γ TNat + | TP_CTX_FAAR Γ e1 : + Γ ⊢ₜ e1 : Tref TNat → + typed_ctx_item (CTX_FAAR e1) Γ TNat Γ TNat + | TP_CTX_CasL Γ e1 e2 τ : EqType τ → UnboxedType τ → typed Γ e1 τ → typed Γ e2 τ → - typed_ctx_item (CTX_CmpXchg_L e1 e2) Γ (Tref τ) Γ (TProd τ TBool) + typed_ctx_item (CTX_CmpXchgL e1 e2) Γ (Tref τ) Γ (TProd τ TBool) | TP_CTX_CasM Γ e0 e2 τ : EqType τ → UnboxedType τ → typed Γ e0 (Tref τ) → typed Γ e2 τ → - typed_ctx_item (CTX_CmpXchg_M e0 e2) Γ τ Γ (TProd τ TBool) + typed_ctx_item (CTX_CmpXchgM e0 e2) Γ τ Γ (TProd τ TBool) | TP_CTX_CasR Γ e0 e1 τ : EqType τ → UnboxedType τ → typed Γ e0 (Tref τ) → typed Γ e1 τ → - typed_ctx_item (CTX_CmpXchg_R e0 e1) Γ τ Γ (TProd τ TBool). + typed_ctx_item (CTX_CmpXchgR e0 e1) Γ τ Γ (TProd τ TBool) + (* Polymorphic & recursive types *) + | TP_CTX_Fold Γ τ : + typed_ctx_item CTX_Fold Γ τ.[(TRec τ)/] Γ (TRec τ) + | TP_CTX_Unfold Γ τ : + typed_ctx_item CTX_Unfold Γ (TRec τ) Γ τ.[(TRec τ)/] + | TP_CTX_TLam Γ τ : + typed_ctx_item CTX_TLam (Autosubst_Classes.subst (ren (+1%nat)) <$> Γ) τ Γ (TForall τ) + | TP_CTX_TApp Γ τ τ' : + typed_ctx_item CTX_TApp Γ (TForall τ) Γ τ.[τ'/] + (* | TP_CTX_Pack Γ τ τ' : *) + (* typed_ctx_item CTX_Pack Γ τ.[τ'/] Γ (TExists τ) *) + | TP_CTX_UnpackL x e2 Γ τ τ2 : + <[x:=τ]>(⤉ Γ) ⊢ₜ e2 : (Autosubst_Classes.subst (ren (+1%nat)) τ2) → + typed_ctx_item (CTX_UnpackL x e2) Γ (TExists τ) Γ τ2 + | TP_CTX_UnpackR x e1 Γ τ τ2 : + Γ ⊢ₜ e1 : TExists τ → + typed_ctx_item (CTX_UnpackR x e1) + (<[x:=τ]>(⤉ Γ)) (Autosubst_Classes.subst (ren (+1%nat)) τ2) + Γ τ2 +. Inductive typed_ctx: ctx → stringmap type → type → stringmap type → type → Prop := | TPCTX_nil Γ τ : @@ -263,6 +291,14 @@ Proof. eapply typed_ctx_compose; eauto. Qed. + +Definition ctx_equiv Γ e1 e2 τ := + (Γ ⊨ e1 ≤ctx≤ e2 : τ) ∧ (Γ ⊨ e2 ≤ctx≤ e1 : τ). + +Notation "Γ ⊨ e '=ctx=' e' : τ" := + (ctx_equiv Γ e e' τ) (at level 100, e, e' at next level, τ at level 200). + + Section bin_log_related_under_typed_ctx. Context `{relocG Σ}. @@ -288,6 +324,27 @@ Section bin_log_related_under_typed_ctx. + iApply (bin_log_related_app _ _ _ _ _ _ τ2 with "[]"). by iApply fundamental. iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_nat_binop with "[]"); + try (by iApply fundamental); eauto. + iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_nat_binop with "[]"); + try (by iApply fundamental); eauto. + iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_bool_binop with "[]"); + try (by iApply fundamental); eauto. + iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_bool_binop with "[]"); + try (by iApply fundamental); eauto. + iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_if with "[] []"); + try by iApply fundamental. + iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_if with "[] []"); + try by iApply fundamental. + iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_if with "[] []"); + try by iApply fundamental. + iApply (IHK with "[Hrel]"); auto. + iApply (bin_log_related_pair with "[]"). iApply (IHK with "[Hrel]"); auto. by iApply fundamental. @@ -314,42 +371,6 @@ Section bin_log_related_under_typed_ctx. by iApply fundamental. by iApply fundamental. iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_if with "[] []"); - try by iApply fundamental. - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_if with "[] []"); - try by iApply fundamental. - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_if with "[] []"); - try by iApply fundamental. - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_nat_binop with "[]"); - try (by iApply fundamental); eauto. - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_nat_binop with "[]"); - try (by iApply fundamental); eauto. - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_bool_binop with "[]"); - try (by iApply fundamental); eauto. - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_bool_binop with "[]"); - try (by iApply fundamental); eauto. - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_fold with "[]"). - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_unfold with "[]"). - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_tlam with "[]"). - iIntros (τi). iAlways. - iApply (IHK with "[Hrel]"); auto. - + iApply (bin_log_related_tapp' with "[]"). - iApply (IHK with "[Hrel]"); auto. - (* + iApply bin_log_related_pack'. *) - (* iApply (IHK with "[Hrel]"); auto. *) - (* + iApply bin_log_related_unpack; try by (iIntros; fundamental). *) - (* iApply (IHK with "[Hrel]"); auto. *) - (* + iApply bin_log_related_unpack; try by (iIntros; fundamental). *) - (* iIntros. iApply (IHK with "[Hrel]"); auto. *) + iApply (bin_log_related_fork with "[]"). iApply (IHK with "[Hrel]"); auto. + iApply (bin_log_related_alloc with "[]"). @@ -362,6 +383,12 @@ Section bin_log_related_under_typed_ctx. + iApply (bin_log_related_store with "[]"); try by iApply fundamental. iApply (IHK with "[Hrel]"); auto. + + iApply bin_log_related_FAA; + try (by iApply fundamental); eauto. + iApply (IHK with "Hrel"). + + iApply bin_log_related_FAA; + try (by iApply fundamental); eauto. + iApply (IHK with "Hrel"). + iApply (bin_log_related_CmpXchg with "[] []"); try (by iApply fundamental); eauto. iApply (IHK with "[Hrel]"); auto. @@ -371,5 +398,20 @@ Section bin_log_related_under_typed_ctx. + iApply (bin_log_related_CmpXchg with "[] []"); try (by iApply fundamental); eauto. iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_fold with "[]"). + iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_unfold with "[]"). + iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_tlam with "[]"). + iIntros (τi). iAlways. + iApply (IHK with "[Hrel]"); auto. + + iApply (bin_log_related_tapp' with "[]"). + iApply (IHK with "[Hrel]"); auto. + + iApply bin_log_related_unpack. + * iApply (IHK with "[Hrel]"); auto. + * iIntros (A). by iApply fundamental. + + iApply bin_log_related_unpack. + * by iApply fundamental. + * iIntros (A). iApply (IHK with "[Hrel]"); auto. Qed. End bin_log_related_under_typed_ctx. diff --git a/theories/typing/fundamental.v b/theories/typing/fundamental.v index 4b2d7e8a998e86938e4a5a4997453983c32fce6b..74d4d01800a09d9d3cea6cd26e065431ed2127ca 100644 --- a/theories/typing/fundamental.v +++ b/theories/typing/fundamental.v @@ -274,6 +274,29 @@ Section fundamental. - by iApply "IH2". Qed. + Lemma bin_log_related_FAA Δ Γ e1 e2 e1' e2' : + ({Δ;Γ} ⊨ e1 ≤log≤ e1' : Tref TNat) -∗ + ({Δ;Γ} ⊨ e2 ≤log≤ e2' : TNat) -∗ + {Δ;Γ} ⊨ FAA e1 e2 ≤log≤ FAA e1' e2' : TNat. + Proof. + iIntros "IH1 IH2". + intro_clause. + rel_bind_ap e2 e2' "IH2" v2 v2' "#IH2". + rel_bind_ap e1 e1' "IH1" v1 v1' "#IH1". + iDestruct "IH1" as (l l') "(% & % & Hinv)"; simplify_eq/=. + iDestruct "IH2" as (n) "[% %]". simplify_eq. + rel_apply_l refines_faa_l. + iInv (relocN .@ "ref" .@ (l,l')) as (v1 v1') "[Hv1 [>Hv2 #>Hv]]" "Hclose". + iDestruct "Hv" as (n1) "[% %]"; simplify_eq. + iModIntro. iExists _; iFrame. iNext. + iIntros "Hl". + (* TODO: tactics for these operations *) + rel_apply_r (refines_faa_r with "Hv2"). iIntros "Hv2". + iMod ("Hclose" with "[-]") as "_". + { iNext. iExists _,_. iFrame. iExists _; iSplit; eauto. } + rel_values. + Qed. + Lemma bin_log_related_CmpXchg Δ Γ e1 e2 e3 e1' e2' e3' τ (HEqτ : EqType τ) (HUbτ : UnboxedType τ) : @@ -518,6 +541,8 @@ Section fundamental. + iApply bin_log_related_alloc; by iApply fundamental. + iApply bin_log_related_load; by iApply fundamental. + iApply bin_log_related_store; by iApply fundamental. + + iApply bin_log_related_FAA; eauto; + by iApply fundamental. + iApply bin_log_related_CmpXchg; eauto; by iApply fundamental. - intros Hv. destruct Hv; simpl. diff --git a/theories/typing/tactics.v b/theories/typing/tactics.v new file mode 100644 index 0000000000000000000000000000000000000000..817fb070dfe58413119ab477df56fc57b8a67643 --- /dev/null +++ b/theories/typing/tactics.v @@ -0,0 +1,84 @@ +From reloc.typing Require Export types contextual_refinement. + +Lemma tac_ctx_bind_l e' C Γ e t τ : + e = fill_ctx C e' → + ctx_refines Γ (fill_ctx C e') t τ → + ctx_refines Γ e t τ. +Proof. intros; subst; assumption. Qed. + +Lemma tac_ctx_bind_r e' C Γ e t τ : + e = fill_ctx C e' → + ctx_refines Γ t (fill_ctx C e') τ → + ctx_refines Γ t e τ. +Proof. intros; subst; assumption. Qed. + +Ltac reshape_expr_ctx e tac := + let rec go K e := + match e with + | _ => tac (reverse K) e + (* Base lambda calculus *) + + | Rec ?f ?x ?e => add_item (CTX_Rec f x) K e + | App ?e1 ?e2 => add_item (CTX_AppL e2) K e1 + | App ?e1 ?e2 => add_item (CTX_AppR e1) K e2 + (* Base types and their operations *) + | UnOp ?op ?e => add_item (UnOpCtx op) K e + | BinOp ?op ?e1 ?e2 => add_item (CTX_BinOpL op e2) K e1 + | BinOp ?op ?e1 ?e2 => add_item (CTX_BinOpR op e1) K e2 + | If ?e0 ?e1 ?e2 => add_item (CTX_IfL e1 e2) K e0 + | If ?e0 ?e1 ?e2 => add_item (CTX_IfM e0 e2) K e1 + | If ?e0 ?e1 ?e2 => add_item (CTX_IfR e0 e1) K e2 + (* Products *) + | Pair ?e1 ?e2 => add_item (CTX_PairL e2) K e1 + | Pair ?e1 ?e2 => add_item (CTX_PairR e1) K e2 + | Fst ?e => add_item CTX_Fst K e + | Snd ?e => add_item CTX_Snd K e + (* Sums *) + | InjL ?e => add_item CTX_InjL K e + | InjR ?e => add_item CTX_InjR K e + | Case ?e0 ?e1 ?e2 => add_item (CTX_CaseL e1 e2) K e0 + | Case ?e0 ?e1 ?e2 => add_item (CTX_CaseM e0 e2) K e1 + | Case ?e0 ?e1 ?e2 => add_item (CTX_CaseR e0 e1) K e2 + (* Concurrency *) + | Fork ?e => add_item CTX_Fork K e + (* Heap *) + | Alloc ?e => add_item CTX_Alloc K e + | Load ?e => add_item CTX_Load K e + | Store ?e1 ?e2 => add_item (CTX_StoreR e1) K e2 + | Store ?e1 ?e2 => add_item (CTX_StoreL e2) K e1 + (* Compare-exchange *) + | CmpXchg ?e0 ?e1 ?e2 => add_item (CTX_CmpXchgL e1 e2) K e0 + | CmpXchg ?e0 ?e1 ?e2 => add_item (CTX_CmpXchgM e0 e2) K e1 + | CmpXchg ?e0 ?e1 ?e2 => add_item (CTX_CmpXchgR e0 e1) K e2 + | FAA ?e0 ?e1 => add_item (CTX_FAAL e1) K e0 + | FAA ?e0 ?e1 => add_item (CTX_FAAR e0) K e1 + end + with add_item Ki K e := go (Ki :: K) e + in + go (@nil ctx_item) e. + +Ltac ctx_bind_helper := + simpl; + lazymatch goal with + | |- fill_ctx ?K ?e = fill_ctx _ ?efoc => + reshape_expr_ctx e ltac:(fun K' e' => + unify e' efoc; + let K'' := eval cbn[app] in (K' ++ K) in + replace (fill_ctx K e) with (fill_ctx K'' e') by (by rewrite ?fill_ctx_app)) + | |- ?e = fill_ctx _ ?efoc => + reshape_expr_ctx e ltac:(fun K' e' => + unify e' efoc; + replace e with (fill_ctx K' e') by (by rewrite ?fill_ctx_app)) + end; reflexivity. + +Tactic Notation "ctx_bind_l" open_constr(efoc) := + eapply (tac_ctx_bind_l efoc); + [ ctx_bind_helper + | (* new goal *) + ]. + +Tactic Notation "ctx_bind_r" open_constr(efoc) := + eapply (tac_ctx_bind_r efoc); + [ ctx_bind_helper + | (* new goal *) + ]. diff --git a/theories/typing/types.v b/theories/typing/types.v index 64f5f1ac0a274a9ddf8b9d976a180bdcf5ac4d8c..c94c6d6c02f748c6b0f4231415d6b07173ceafcf 100644 --- a/theories/typing/types.v +++ b/theories/typing/types.v @@ -106,9 +106,12 @@ Inductive typed : stringmap type → expr → type → Prop := | Val_typed Γ v τ : ⊢ᵥ v : τ → Γ ⊢ₜ Val v : τ - | Unit_typed Γ : Γ ⊢ₜ #() : TUnit - | Nat_typed Γ (n : nat) : Γ ⊢ₜ # n : TNat - | Bool_typed Γ (b : bool) : Γ ⊢ₜ # b : TBool + | Unit_typed Γ : + Γ ⊢ₜ #() : TUnit + | Nat_typed Γ (n : nat) : + Γ ⊢ₜ #n : TNat + | Bool_typed Γ (b : bool) : + Γ ⊢ₜ #b : TBool | BinOp_typed_nat Γ op e1 e2 τ : Γ ⊢ₜ e1 : TNat → Γ ⊢ₜ e2 : TNat → binop_nat_res_type op = Some τ → @@ -120,39 +123,65 @@ Inductive typed : stringmap type → expr → type → Prop := | RefEq_typed Γ e1 e2 τ : Γ ⊢ₜ e1 : Tref τ → Γ ⊢ₜ e2 : Tref τ → Γ ⊢ₜ BinOp EqOp e1 e2 : TBool - | Pair_typed Γ e1 e2 τ1 τ2 : Γ ⊢ₜ e1 : τ1 → Γ ⊢ₜ e2 : τ2 → Γ ⊢ₜ Pair e1 e2 : TProd τ1 τ2 - | Fst_typed Γ e τ1 τ2 : Γ ⊢ₜ e : TProd τ1 τ2 → Γ ⊢ₜ Fst e : τ1 - | Snd_typed Γ e τ1 τ2 : Γ ⊢ₜ e : TProd τ1 τ2 → Γ ⊢ₜ Snd e : τ2 - | InjL_typed Γ e τ1 τ2 : Γ ⊢ₜ e : τ1 → Γ ⊢ₜ InjL e : TSum τ1 τ2 - | InjR_typed Γ e τ1 τ2 : Γ ⊢ₜ e : τ2 → Γ ⊢ₜ InjR e : TSum τ1 τ2 + | Pair_typed Γ e1 e2 τ1 τ2 : + Γ ⊢ₜ e1 : τ1 → Γ ⊢ₜ e2 : τ2 → + Γ ⊢ₜ (e1, e2) : τ1 * τ2 + | Fst_typed Γ e τ1 τ2 : + Γ ⊢ₜ e : τ1 * τ2 → + Γ ⊢ₜ Fst e : τ1 + | Snd_typed Γ e τ1 τ2 : + Γ ⊢ₜ e : τ1 * τ2 → + Γ ⊢ₜ Snd e : τ2 + | InjL_typed Γ e τ1 τ2 : + Γ ⊢ₜ e : τ1 → + Γ ⊢ₜ InjL e : τ1 + τ2 + | InjR_typed Γ e τ1 τ2 : + Γ ⊢ₜ e : τ2 → + Γ ⊢ₜ InjR e : τ1 + τ2 | Case_typed Γ e0 e1 e2 τ1 τ2 τ3 : - Γ ⊢ₜ e0 : TSum τ1 τ2 → - Γ ⊢ₜ e1 : TArrow τ1 τ3 → - Γ ⊢ₜ e2 : TArrow τ2 τ3 → + Γ ⊢ₜ e0 : τ1 + τ2 → + Γ ⊢ₜ e1 : (τ1 → τ3) → + Γ ⊢ₜ e2 : (τ2 → τ3) → Γ ⊢ₜ Case e0 e1 e2 : τ3 | If_typed Γ e0 e1 e2 τ : - Γ ⊢ₜ e0 : TBool → Γ ⊢ₜ e1 : τ → Γ ⊢ₜ e2 : τ → Γ ⊢ₜ If e0 e1 e2 : τ + Γ ⊢ₜ e0 : TBool → + Γ ⊢ₜ e1 : τ → + Γ ⊢ₜ e2 : τ → + Γ ⊢ₜ If e0 e1 e2 : τ | Rec_typed Γ f x e τ1 τ2 : - <[f:=TArrow τ1 τ2]>(<[x:=τ1]>Γ) ⊢ₜ e : τ2 → - Γ ⊢ₜ Rec f x e : TArrow τ1 τ2 + <[f:=(τ1 → τ2)%ty]>(<[x:=τ1]>Γ) ⊢ₜ e : τ2 → + Γ ⊢ₜ (rec: f x := e) : (τ1 → τ2) | App_typed Γ e1 e2 τ1 τ2 : - Γ ⊢ₜ e1 : TArrow τ1 τ2 → Γ ⊢ₜ e2 : τ1 → Γ ⊢ₜ App e1 e2 : τ2 + Γ ⊢ₜ e1 : (τ1 → τ2) → + Γ ⊢ₜ e2 : τ1 → + Γ ⊢ₜ e1 e2 : τ2 | TLam_typed Γ e τ : ⤉ Γ ⊢ₜ e : τ → - Γ ⊢ₜ (Λ: e) : TForall τ - | TApp_typed Γ e τ τ' : Γ ⊢ₜ e : TForall τ → + Γ ⊢ₜ (Λ: e) : ∀: τ + | TApp_typed Γ e τ τ' : + Γ ⊢ₜ e : (∀: τ) → Γ ⊢ₜ e #() : τ.[τ'/] - | TFold Γ e τ : Γ ⊢ₜ e : τ.[TRec τ/] → Γ ⊢ₜe : TRec τ - | TUnfold Γ e τ : Γ ⊢ₜ e : TRec τ → Γ ⊢ₜ rec_unfold e : τ.[TRec τ/] - | TPack Γ e τ τ' : Γ ⊢ₜ e : τ.[τ'/] → Γ ⊢ₜ e : TExists τ + | TFold Γ e τ : + Γ ⊢ₜ e : τ.[(μ: τ)%ty/] → + Γ ⊢ₜ e : (μ: τ) + | TUnfold Γ e τ : + Γ ⊢ₜ e : (μ: τ)%ty → + Γ ⊢ₜ rec_unfold e : τ.[(μ: τ)%ty/] + | TPack Γ e τ τ' : + Γ ⊢ₜ e : τ.[τ'/] → + Γ ⊢ₜ e : (∃: τ) | TUnpack Γ e1 x e2 τ τ2 : - Γ ⊢ₜ e1 : TExists τ → + Γ ⊢ₜ e1 : (∃: τ) → <[x:=τ]>(⤉ Γ) ⊢ₜ e2 : (Autosubst_Classes.subst (ren (+1%nat)) τ2) → Γ ⊢ₜ (unpack: x := e1 in e2) : τ2 | TFork Γ e : Γ ⊢ₜ e : TUnit → Γ ⊢ₜ Fork e : TUnit | TAlloc Γ e τ : Γ ⊢ₜ e : τ → Γ ⊢ₜ Alloc e : Tref τ | TLoad Γ e τ : Γ ⊢ₜ e : Tref τ → Γ ⊢ₜ Load e : τ | TStore Γ e e' τ : Γ ⊢ₜ e : Tref τ → Γ ⊢ₜ e' : τ → Γ ⊢ₜ Store e e' : TUnit + | TFAA Γ e1 e2 : + Γ ⊢ₜ e1 : Tref TNat → + Γ ⊢ₜ e2 : TNat → + Γ ⊢ₜ FAA e1 e2 : TNat | TCmpXchg Γ e1 e2 e3 τ : EqType τ → UnboxedType τ → Γ ⊢ₜ e1 : Tref τ → Γ ⊢ₜ e2 : τ → Γ ⊢ₜ e3 : τ →