Skip to content
Snippets Groups Projects
Commit ea190f98 authored by Ralf Jung's avatar Ralf Jung
Browse files

implement heap allocation and loading

parent 39213728
No related branches found
No related tags found
No related merge requests found
Require Import mathcomp.ssreflect.ssreflect. Require Import mathcomp.ssreflect.ssreflect.
Require Import Autosubst.Autosubst. Require Import Autosubst.Autosubst.
Require Import prelude.option iris.language. Require Import prelude.option prelude.gmap iris.language.
Set Bullet Behavior "Strict Subproofs". Set Bullet Behavior "Strict Subproofs".
...@@ -26,20 +26,28 @@ Ltac case_depeq3 := let Heq := fresh "Heq" in ...@@ -26,20 +26,28 @@ Ltac case_depeq3 := let Heq := fresh "Heq" in
Definition loc := nat. (* Any countable type. *) Definition loc := nat. (* Any countable type. *)
Inductive expr := Inductive expr :=
(* Base lambda calculus *)
| Var (x : var) | Var (x : var)
| Rec (e : {bind 2 of expr}) (* These are recursive lambdas. *) | Rec (e : {bind 2 of expr}) (* These are recursive lambdas. *)
| App (e1 e2 : expr) | App (e1 e2 : expr)
| Loc (l : loc) (* Embedding of Coq values and operations *)
| Lit {T : Type} (t: T) (* arbitrary Coq values become literals *) | Lit {T : Type} (t: T) (* arbitrary Coq values become literals *)
| Op1 {T1 To : Type} (f : T1 -> To) (e1 : expr) | Op1 {T1 To : Type} (f : T1 -> To) (e1 : expr)
| Op2 {T1 T2 To : Type} (f : T1 -> T2 -> To) (e1 : expr) (e2 : expr) | Op2 {T1 T2 To : Type} (f : T1 -> T2 -> To) (e1 : expr) (e2 : expr)
(* Products *)
| Pair (e1 e2 : expr) | Pair (e1 e2 : expr)
| Fst (e : expr) | Fst (e : expr)
| Snd (e : expr) | Snd (e : expr)
(* Sums *)
| InjL (e : expr) | InjL (e : expr)
| InjR (e : expr) | InjR (e : expr)
| Case (e0 : expr) (e1 : {bind expr}) (e2 : {bind expr}) | Case (e0 : expr) (e1 : {bind expr}) (e2 : {bind expr})
| Fork (e : expr). (* Concurrency *)
| Fork (e : expr)
(* Heap *)
| Loc (l : loc)
| Ref (e : expr)
| Load ( e : expr).
Instance Ids_expr : Ids expr. derive. Defined. Instance Ids_expr : Ids expr. derive. Defined.
Instance Rename_expr : Rename expr. derive. Defined. Instance Rename_expr : Rename expr. derive. Defined.
...@@ -51,32 +59,32 @@ Definition LitUnit := Lit tt. ...@@ -51,32 +59,32 @@ Definition LitUnit := Lit tt.
Inductive value := Inductive value :=
| RecV (e : {bind 2 of expr}) | RecV (e : {bind 2 of expr})
| LocV (l : loc)
| LitV (T : Type) (t : T) (* arbitrary Coq values become literal values *) | LitV (T : Type) (t : T) (* arbitrary Coq values become literal values *)
| PairV (v1 v2 : value) | PairV (v1 v2 : value)
| InjLV (v : value) | InjLV (v : value)
| InjRV (v : value). | InjRV (v : value)
| LocV (l : loc).
Fixpoint v2e (v : value) : expr := Fixpoint v2e (v : value) : expr :=
match v with match v with
| LitV _ t => Lit t | LitV _ t => Lit t
| LocV l => Loc l
| RecV e => Rec e | RecV e => Rec e
| PairV v1 v2 => Pair (v2e v1) (v2e v2) | PairV v1 v2 => Pair (v2e v1) (v2e v2)
| InjLV v => InjL (v2e v) | InjLV v => InjL (v2e v)
| InjRV v => InjR (v2e v) | InjRV v => InjR (v2e v)
| LocV l => Loc l
end. end.
Fixpoint e2v (e : expr) : option value := Fixpoint e2v (e : expr) : option value :=
match e with match e with
| Rec e => Some (RecV e) | Rec e => Some (RecV e)
| Loc l => Some (LocV l)
| Lit T t => Some (LitV T t) | Lit T t => Some (LitV T t)
| Pair e1 e2 => v1 e2v e1; | Pair e1 e2 => v1 e2v e1;
v2 e2v e2; v2 e2v e2;
Some (PairV v1 v2) Some (PairV v1 v2)
| InjL e => InjLV <$> e2v e | InjL e => InjLV <$> e2v e
| InjR e => InjRV <$> e2v e | InjR e => InjRV <$> e2v e
| Loc l => Some (LocV l)
| _ => None | _ => None
end. end.
...@@ -108,8 +116,8 @@ Proof. ...@@ -108,8 +116,8 @@ Proof.
first [case_depeq3 | case_depeq2 | case_depeq1 | case]; eauto using f_equal, f_equal2. first [case_depeq3 | case_depeq2 | case_depeq1 | case]; eauto using f_equal, f_equal2.
Qed. Qed.
(** The state: heaps. *) (** The state: heaps of values. *)
Definition state := unit. Definition state := gmap loc value.
(** Evaluation contexts *) (** Evaluation contexts *)
Inductive ectx := Inductive ectx :=
...@@ -125,7 +133,9 @@ Inductive ectx := ...@@ -125,7 +133,9 @@ Inductive ectx :=
| SndCtx (K : ectx) | SndCtx (K : ectx)
| InjLCtx (K : ectx) | InjLCtx (K : ectx)
| InjRCtx (K : ectx) | InjRCtx (K : ectx)
| CaseCtx (K : ectx) (e1 : {bind expr}) (e2 : {bind expr}). | CaseCtx (K : ectx) (e1 : {bind expr}) (e2 : {bind expr})
| RefCtx (K : ectx)
| LoadCtx (K : ectx).
Fixpoint fill (K : ectx) (e : expr) := Fixpoint fill (K : ectx) (e : expr) :=
match K with match K with
...@@ -142,6 +152,8 @@ Fixpoint fill (K : ectx) (e : expr) := ...@@ -142,6 +152,8 @@ Fixpoint fill (K : ectx) (e : expr) :=
| InjLCtx K => InjL (fill K e) | InjLCtx K => InjL (fill K e)
| InjRCtx K => InjR (fill K e) | InjRCtx K => InjR (fill K e)
| CaseCtx K e1 e2 => Case (fill K e) e1 e2 | CaseCtx K e1 e2 => Case (fill K e) e1 e2
| RefCtx K => Ref (fill K e)
| LoadCtx K => Load (fill K e)
end. end.
Fixpoint comp_ctx (Ko : ectx) (Ki : ectx) := Fixpoint comp_ctx (Ko : ectx) (Ki : ectx) :=
...@@ -159,6 +171,8 @@ Fixpoint comp_ctx (Ko : ectx) (Ki : ectx) := ...@@ -159,6 +171,8 @@ Fixpoint comp_ctx (Ko : ectx) (Ki : ectx) :=
| InjLCtx K => InjLCtx (comp_ctx K Ki) | InjLCtx K => InjLCtx (comp_ctx K Ki)
| InjRCtx K => InjRCtx (comp_ctx K Ki) | InjRCtx K => InjRCtx (comp_ctx K Ki)
| CaseCtx K e1 e2 => CaseCtx (comp_ctx K Ki) e1 e2 | 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)
end. end.
Lemma fill_empty e : Lemma fill_empty e :
...@@ -217,11 +231,21 @@ Inductive prim_step : expr -> state -> expr -> state -> option expr -> Prop := ...@@ -217,11 +231,21 @@ Inductive prim_step : expr -> state -> expr -> state -> option expr -> Prop :=
| CaseRS e0 v0 e1 e2 σ (Hv0 : e2v e0 = Some v0): | CaseRS e0 v0 e1 e2 σ (Hv0 : e2v e0 = Some v0):
prim_step (Case (InjR e0) e1 e2) σ (e2.[e0/]) σ None prim_step (Case (InjR e0) e1 e2) σ (e2.[e0/]) σ None
| ForkS e σ: | ForkS e σ:
prim_step (Fork e) σ LitUnit σ (Some e). 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.
Definition reducible e: Prop := Definition reducible e: Prop :=
exists σ e' σ' ef, prim_step e σ e' σ' ef. exists σ e' σ' ef, prim_step e σ e' σ' ef.
Lemma reducible_not_value e:
reducible e -> e2v e = None.
Proof.
intros (σ' & e'' & σ'' & ef & Hstep). destruct Hstep; simpl in *; reflexivity.
Qed.
Definition stuck (e : expr) : Prop := Definition stuck (e : expr) : Prop :=
forall K e', forall K e',
e = fill K e' -> e = fill K e' ->
...@@ -233,10 +257,10 @@ Proof. ...@@ -233,10 +257,10 @@ Proof.
intros ?? Heq. intros ?? Heq.
edestruct (fill_value K) as [v' Hv']. edestruct (fill_value K) as [v' Hv'].
{ by rewrite <-Heq, v2v. } { by rewrite <-Heq, v2v. }
clear -Hv'. intros (σ' & e'' & σ'' & ef & Hstep). destruct Hstep; simpl in *; discriminate. clear -Hv' => Hred. apply reducible_not_value in Hred.
destruct (e2v e'); discriminate.
Qed. Qed.
Section step_by_value. Section step_by_value.
(* When something does a step, and another decomposition of the same (* When something does a step, and another decomposition of the same
expression has a non-value e in the hole, then K is a left expression has a non-value e in the hole, then K is a left
...@@ -252,7 +276,7 @@ Proof. ...@@ -252,7 +276,7 @@ Proof.
intros; subst; intros; subst;
(eapply values_stuck; eassumption) || (eapply fill_not_value2; first eassumption; (eapply values_stuck; eassumption) || (eapply fill_not_value2; first eassumption;
by erewrite ?Hfill, ?v2v). by erewrite ?Hfill, ?v2v).
Ltac bad_red Hfill e' Hred := exfalso; destruct e'; try discriminate; []; Ltac bad_red Hfill e' Hred := exfalso; destruct e'; try discriminate Hfill; [];
case: Hfill; intros; subst; destruct Hred as (σ' & e'' & σ'' & ef & Hstep); case: Hfill; intros; subst; destruct Hred as (σ' & e'' & σ'' & ef & Hstep);
inversion Hstep; done || (clear Hstep; subst; inversion Hstep; done || (clear Hstep; subst;
eapply fill_not_value2; last ( eapply fill_not_value2; last (
...@@ -264,23 +288,48 @@ Proof. ...@@ -264,23 +288,48 @@ Proof.
exists K''; by eauto using f_equal, f_equal2, f_equal3, v2e_inj. exists K''; by eauto using f_equal, f_equal2, f_equal3, v2e_inj.
intros Hfill Hred Hnval. intros Hfill Hred Hnval.
Time revert K' Hfill; induction K=>K' /= Hfill; try first [ revert K' Hfill; induction K=>K' /= Hfill;
now eexists; reflexivity first (now eexists; reflexivity);
| destruct K'; simpl; try discriminate; try first [ destruct K'; simpl; try discriminate Hfill; try first [
bad_red Hfill e' Hred bad_red Hfill e' Hred
| bad_fill Hfill | bad_fill Hfill
| good Hfill IHK | good Hfill IHK
] ].
].
Qed. Qed.
End step_by_value. End step_by_value.
(** Atomic expressions *) (** Atomic expressions *)
Definition atomic (e: expr) := Definition atomic (e: expr) :=
match e with match e with
| Ref e => is_Some (e2v e)
| Load e => is_Some (e2v e)
| _ => False | _ => False
end. end.
Lemma atomic_not_value e :
atomic e -> e2v e = None.
Proof.
destruct e; simpl; contradiction || reflexivity.
Qed.
Lemma atomic_step e1 σ1 e2 σ2 ef :
atomic e1 ->
prim_step e1 σ1 e2 σ2 ef ->
is_Some (e2v e2).
Proof.
destruct e1; simpl; intros Hatomic Hstep; inversion Hstep; try contradiction Hatomic; rewrite ?v2v /=; eexists; reflexivity.
Qed.
(* Atomics must not contain evaluation positions. *)
Lemma atomic_fill e K :
atomic (fill K e) ->
e2v e = None ->
K = EmptyCtx.
Proof.
destruct K; simpl; first reflexivity; intros Hatomic Hnval; exfalso; try assumption;
destruct Hatomic; eapply fill_not_value2; eassumption.
Qed.
(** Tests, making sure that stuff works. *) (** Tests, making sure that stuff works. *)
Module Tests. Module Tests.
Definition add := Op2 plus (Lit 21) (Lit 21). Definition add := Op2 plus (Lit 21) (Lit 21).
...@@ -318,11 +367,13 @@ Section Language. ...@@ -318,11 +367,13 @@ Section Language.
- exact v2v. - exact v2v.
- exact e2e. - exact e2e.
- intros e1 σ1 e2 σ2 ef (K & e1' & e2' & He1 & He2 & Hstep). subst e1 e2. - intros e1 σ1 e2 σ2 ef (K & e1' & e2' & He1 & He2 & Hstep). subst e1 e2.
eapply fill_not_value. case Heq:(e2v e1') => [v1'|]; last done. exfalso. eapply fill_not_value. eapply reducible_not_value. do 4 eexists; eassumption.
eapply values_stuck; last by (do 4 eexists; eassumption). erewrite fill_empty. - exact atomic_not_value.
eapply e2e. eassumption. - intros ? ? ? ? ? Hatomic (K & e1' & e2' & Heq1 & Heq2 & Hstep).
- intros. contradiction. subst. move: (Hatomic). rewrite (atomic_fill e1' K). (* RJ: this is kind of annoying. *)
- intros. contradiction. + rewrite !fill_empty. eauto using atomic_step.
+ assumption.
+ clear Hatomic. eapply reducible_not_value. do 4 eexists; eassumption.
Defined. Defined.
(** We can have bind with arbitrary evaluation contexts **) (** We can have bind with arbitrary evaluation contexts **)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment