diff --git a/channel/heap_lang.v b/channel/heap_lang.v index a9d6ccc83ed323bdc0dbcf4a52256d2d9ecbcccc..45a1f8ba54fb0e969cc57c5dc7e031d5d9ddd913 100644 --- a/channel/heap_lang.v +++ b/channel/heap_lang.v @@ -47,7 +47,10 @@ Inductive expr := (* Heap *) | Loc (l : loc) | Ref (e : expr) -| Load ( e : expr). +| Load (e : expr) +| Store (e1 : expr) (e2 : expr) +| Cas (e0 : expr) (e1 : expr) (e2 : expr) +. Instance Ids_expr : Ids expr. derive. Defined. Instance Rename_expr : Rename expr. derive. Defined. @@ -56,6 +59,8 @@ Instance SubstLemmas_expr : SubstLemmas expr. derive. Qed. Definition Lam (e: expr) := Rec (e.[up ids]). Definition LitUnit := Lit tt. +Definition LitTrue := Lit true. +Definition LitFalse := Lit false. Inductive value := | RecV (e : {bind 2 of expr}) @@ -63,7 +68,8 @@ Inductive value := | PairV (v1 v2 : value) | InjLV (v : value) | InjRV (v : value) -| LocV (l : loc). +| LocV (l : loc) +. Fixpoint v2e (v : value) : expr := match v with @@ -113,7 +119,7 @@ Lemma v2e_inj v1 v2: v2e v1 = v2e v2 -> v1 = v2. Proof. revert v2; induction v1=>v2; destruct v2; simpl; try discriminate; - first [case_depeq3 | case_depeq2 | case_depeq1 | case]; eauto using f_equal, f_equal2. + first [case_depeq1 | case]; eauto using f_equal, f_equal2. Qed. (** The state: heaps of values. *) @@ -122,12 +128,12 @@ Definition state := gmap loc value. (** Evaluation contexts *) Inductive ectx := | EmptyCtx -| AppLCtx (K1 : ectx) (e2 : expr) +| AppLCtx (K1 : ectx) (e2 : expr) | AppRCtx (v1 : value) (K2 : ectx) | Op1Ctx {T1 To : Type} (f : T1 -> To) (K : ectx) -| Op2LCtx {T1 T2 To : Type} (f : T1 -> T2 -> To) (K1 : ectx) (e2 : expr) +| Op2LCtx {T1 T2 To : Type} (f : T1 -> T2 -> To) (K1 : ectx) (e2 : expr) | Op2RCtx {T1 T2 To : Type} (f : T1 -> T2 -> To) (v1 : value) (K2 : ectx) -| PairLCtx (K1 : ectx) (e2 : expr) +| PairLCtx (K1 : ectx) (e2 : expr) | PairRCtx (v1 : value) (K2 : ectx) | FstCtx (K : ectx) | SndCtx (K : ectx) @@ -135,7 +141,13 @@ Inductive ectx := | InjRCtx (K : ectx) | CaseCtx (K : ectx) (e1 : {bind expr}) (e2 : {bind expr}) | RefCtx (K : ectx) -| LoadCtx (K : ectx). +| LoadCtx (K : ectx) +| StoreLCtx (K1 : ectx) (e2 : expr) +| StoreRCtx (v1 : value) (K2 : ectx) +| CasLCtx (K0 : ectx) (e1 : expr) (e2 : expr) +| CasMCtx (v0 : value) (K1 : ectx) (e2 : expr) +| CasRCtx (v0 : value) (v1 : value) (K2 : ectx) +. Fixpoint fill (K : ectx) (e : expr) := match K with @@ -154,6 +166,11 @@ Fixpoint fill (K : ectx) (e : expr) := | CaseCtx K e1 e2 => Case (fill K e) e1 e2 | RefCtx K => Ref (fill K e) | LoadCtx K => Load (fill K e) + | StoreLCtx K1 e2 => Store (fill K1 e) e2 + | StoreRCtx v1 K2 => Store (v2e v1) (fill K2 e) + | CasLCtx K0 e1 e2 => Cas (fill K0 e) e1 e2 + | CasMCtx v0 K1 e2 => Cas (v2e v0) (fill K1 e) e2 + | CasRCtx v0 v1 K2 => Cas (v2e v0) (v2e v1) (fill K2 e) end. Fixpoint comp_ctx (Ko : ectx) (Ki : ectx) := @@ -173,6 +190,11 @@ Fixpoint comp_ctx (Ko : ectx) (Ki : ectx) := | CaseCtx K e1 e2 => CaseCtx (comp_ctx K Ki) e1 e2 | RefCtx K => RefCtx (comp_ctx K Ki) | LoadCtx K => LoadCtx (comp_ctx K Ki) + | StoreLCtx K1 e2 => StoreLCtx (comp_ctx K1 Ki) e2 + | StoreRCtx v1 K2 => StoreRCtx v1 (comp_ctx K2 Ki) + | CasLCtx K0 e1 e2 => CasLCtx (comp_ctx K0 Ki) e1 e2 + | CasMCtx v0 K1 e2 => CasMCtx v0 (comp_ctx K1 Ki) e2 + | CasRCtx v0 v1 K2 => CasRCtx v0 v1 (comp_ctx K2 Ki) end. Lemma fill_empty e : @@ -234,8 +256,17 @@ Inductive prim_step : expr -> state -> expr -> state -> option expr -> Prop := prim_step (Fork e) σ LitUnit σ (Some e) | RefS e v σ l (Hv : e2v e = Some v) (Hfresh : σ !! l = None): prim_step (Ref e) σ (Loc l) (<[l:=v]>σ) None -| LoadS l σ v (Hlookup : σ !! l = Some v): - prim_step (Load (Loc l)) σ (v2e v) σ None. +| LoadS l v σ (Hlookup : σ !! l = Some v): + prim_step (Load (Loc l)) σ (v2e v) σ None +| StoreS l e v σ (Hv : e2v e = Some v) (Halloc : is_Some (σ !! l)): + prim_step (Store (Loc l) e) σ LitUnit (<[l:=v]>σ) None +| CasFailS l e1 v1 e2 v2 vl σ (Hv1 : e2v e1 = Some v1) (Hv2 : e2v e2 = Some v2) + (Hlookup : σ !! l = Some vl) (Hne : vl <> v1): + prim_step (Cas (Loc l) e1 e2) σ LitFalse σ None +| CasSucS l e1 v1 e2 v2 σ (Hv1 : e2v e1 = Some v1) (Hv2 : e2v e2 = Some v2) + (Hlookup : σ !! l = Some v1): + prim_step (Cas (Loc l) e1 e2) σ LitTrue (<[l:=v2]>σ) None +. Definition reducible e: Prop := exists σ e' σ' ef, prim_step e σ e' σ' ef. @@ -275,13 +306,14 @@ Proof. Ltac bad_fill Hfill := exfalso; move: Hfill; first [case_depeq3 | case_depeq2 | case_depeq1 | case] =>Hfill; intros; subst; (eapply values_stuck; eassumption) || (eapply fill_not_value2; first eassumption; - by erewrite ?Hfill, ?v2v). + try match goal with [ H : fill _ _ = _ |- _ ] => erewrite ->H end; + by erewrite ?v2v). Ltac bad_red Hfill e' Hred := exfalso; destruct e'; try discriminate Hfill; []; case: Hfill; intros; subst; destruct Hred as (σ' & e'' & σ'' & ef & Hstep); inversion Hstep; done || (clear Hstep; subst; eapply fill_not_value2; last ( try match goal with [ H : _ = fill _ _ |- _ ] => erewrite <-H end; simpl; - repeat match goal with [ H : e2v _ = _ |- _ ] => erewrite H; simpl end + repeat match goal with [ H : e2v _ = _ |- _ ] => erewrite H; clear H; simpl end ); eassumption || done). Ltac good Hfill IH := move: Hfill; first [case_depeq3 | case_depeq2 | case_depeq1 | case]; intros; subst; let K'' := fresh "K''" in edestruct IH as [K'' Hcomp]; first eassumption; @@ -303,6 +335,8 @@ Definition atomic (e: expr) := match e with | Ref e => is_Some (e2v e) | Load e => is_Some (e2v e) + | Store e1 e2 => is_Some (e2v e1) /\ is_Some (e2v e2) + | Cas e0 e1 e2 => is_Some (e2v e0) /\ is_Some (e2v e1) /\ is_Some (e2v e2) | _ => False end. @@ -326,8 +360,8 @@ Lemma atomic_fill e K : e2v e = None -> K = EmptyCtx. Proof. - destruct K; simpl; first reflexivity; intros Hatomic Hnval; exfalso; try assumption; - destruct Hatomic; eapply fill_not_value2; eassumption. + destruct K; simpl; first reflexivity; unfold is_Some; intros Hatomic Hnval; exfalso; try assumption; + try (destruct_conjs; eapply fill_not_value2; eassumption). Qed. (** Tests, making sure that stuff works. *)