Library zoo.language.semantics
From stdpp Require Import
gmap.
From zoo Require Import
prelude.
From zoo.language Require Export
physical_equality
metatheory
state.
From zoo Require Import
options.
Implicit Types b : bool.
Implicit Types tag : nat.
Implicit Types n m : Z.
Implicit Types l : location.
Implicit Types gen : generativity.
Implicit Types mut : mutability.
Implicit Types lit : literal.
Implicit Types x : binder.
Implicit Types e : expr.
Implicit Types es : list expr.
Implicit Types v w : val.
Implicit Types vs : list val.
Implicit Types br : branch.
Implicit Types brs : list branch.
Implicit Types rec : recursive.
Implicit Types recs : list recursive.
Definition thread_id :=
nat.
Implicit Types tid : thread_id.
Parameter encode_tag : nat → nat.
Axiom encode_tag_inj :
Inj (=) (=) encode_tag.
#[global] Existing Instance encode_tag_inj.
Definition val_immediate v :=
match v with
| ValLit lit ⇒
match lit with
| LitBool _
| LitInt _ ⇒
true
| _ ⇒
false
end
| ValRecs _ _ ⇒
false
| ValBlock _ _ [] ⇒
true
| ValBlock _ _ _ ⇒
false
end.
#[global] Arguments val_immediate !_ / : assert.
Definition eval_unop op v :=
match op, v with
| UnopNeg, ValBool b ⇒
Some $ ValBool (¬ b)
| UnopMinus, ValInt n ⇒
Some $ ValInt (- n)
| UnopIsImmediate, v ⇒
Some $ ValBool (val_immediate v)
| _, _ ⇒
None
end.
#[global] Arguments eval_unop !_ !_ / : assert.
Definition eval_binop_int op n1 n2 :=
match op with
| BinopPlus ⇒
LitInt (n1 + n2)
| BinopMinus ⇒
LitInt (n1 - n2)
| BinopMult ⇒
LitInt (n1 × n2)
| BinopQuot ⇒
LitInt (n1 `quot` n2)
| BinopRem ⇒
LitInt (n1 `rem` n2)
| BinopLand ⇒
LitInt (Z.land n1 n2)
| BinopLor ⇒
LitInt (Z.lor n1 n2)
| BinopLsl ⇒
LitInt (n1 ≪ n2)
| BinopLsr ⇒
LitInt (n1 ≫ n2)
| BinopLe ⇒
LitBool (bool_decide (n1 ≤ n2))
| BinopLt ⇒
LitBool (bool_decide (n1 < n2))
| BinopGe ⇒
LitBool (bool_decide (n1 ≥ n2))
| BinopGt ⇒
LitBool (bool_decide (n1 > n2))
end%Z.
#[global] Arguments eval_binop_int !_ _ _ / : assert.
Definition eval_binop op v1 v2 :=
match v1, v2 with
| ValInt n1, ValInt n2 ⇒
Some $ ValLit $ eval_binop_int op n1 n2
| _, _ ⇒
None
end.
#[global] Arguments eval_binop _ !_ !_ / : assert.
Definition eval_app_aux recs i rec :=
subst' rec.1.1 (ValRecs i recs).
Definition eval_app' {A} foldri recs x v e : A :=
foldri (eval_app_aux recs) (subst' x v e).
Definition eval_app recs x v e :=
eval_app' foldri recs x v e recs.
Variant subject :=
| SubjectLoc l
| SubjectBlock gen vs.
Implicit Types subj : subject.
Definition subject_to_val tag subj :=
match subj with
| SubjectLoc l ⇒
ValLoc l
| SubjectBlock gen vs ⇒
ValBlock gen tag vs
end.
Fixpoint eval_match tag sz subj x_fb e_fb brs :=
match brs with
| [] ⇒
Some $ subst' x_fb (subject_to_val tag subj) e_fb
| br :: brs ⇒
let pat := br.1 in
if pat.(pattern_tag) ≟ tag && length pat.(pattern_fields) ≟ sz then
let res := subst' pat.(pattern_as) (subject_to_val tag subj) br.2 in
match subj with
| SubjectLoc l ⇒
if forallb (BAnon ≟.) pat.(pattern_fields) then
Some res
else
None
| SubjectBlock _ vs ⇒
Some $ subst_list pat.(pattern_fields) vs res
end
else
eval_match tag sz subj x_fb e_fb brs
end.
#[global] Arguments eval_match _ _ !_ _ _ !_ / : assert.
Definition observation : Set :=
prophet_id × (val × val).
Inductive base_step tid : expr → state → list observation → expr → state → list expr → Prop :=
| base_step_rec f x e σ :
base_step
tid
(Rec f x e)
σ
[]
(Val $ ValRec f x e)
σ
[]
| base_step_app i recs rec v σ :
recs !! i = Some rec →
base_step
tid
(App (Val $ ValRecs i recs) (Val v))
σ
[]
(eval_app recs rec.1.2 v rec.2)
σ
[]
| base_step_let x v1 e2 σ :
base_step
tid
(Let x (Val v1) e2)
σ
[]
(subst' x v1 e2)
σ
[]
| base_step_unop op v v' σ :
eval_unop op v = Some v' →
base_step
tid
(Unop op $ Val v)
σ
[]
(Val v')
σ
[]
| base_step_binop op v1 v2 v' σ :
eval_binop op v1 v2 = Some v' →
base_step
tid
(Binop op (Val v1) (Val v2))
σ
[]
(Val v')
σ
[]
| base_step_equal_fail v1 v2 σ :
v1 ≉ v2 →
base_step
tid
(Equal (Val v1) (Val v2))
σ
[]
(Val $ ValBool false)
σ
[]
| base_step_equal_success v1 v2 σ :
v1 ≈ v2 →
base_step
tid
(Equal (Val v1) (Val v2))
σ
[]
(Val $ ValBool true)
σ
[]
| base_step_if b e1 e2 σ :
base_step
tid
(If (Val $ ValBool b) e1 e2)
σ
[]
(if b then e1 else e2)
σ
[]
| base_step_for n1 n2 e σ :
base_step
tid
(For (Val $ ValInt n1) (Val $ ValInt n2) e)
σ
[]
(if decide (n2 ≤ n1)%Z then Unit else Seq (App e (Val $ ValInt n1)) (For (Val $ ValInt (n1 + 1)) (Val $ ValInt n2) e))
σ
[]
| base_step_alloc tag n σ l :
(0 ≤ n)%Z →
σ.(state_headers) !! l = None →
( ∀ i,
i < ₊n →
σ.(state_headers) !! (l +ₗ i) = None ∧
σ.(state_heap) !! (l +ₗ i) = None
) →
base_step
tid
(Alloc (Val $ ValNat tag) (Val $ ValInt n))
σ
[]
(Val $ ValLoc l)
(state_alloc l (Header tag ₊n) (replicate ₊n ValUnit) σ)
[]
| base_step_block_mutable tag es vs σ l :
0 < length es →
es = of_vals vs →
σ.(state_headers) !! l = None →
( ∀ i,
i < length es →
σ.(state_headers) !! (l +ₗ i) = None ∧
σ.(state_heap) !! (l +ₗ i) = None
) →
base_step
tid
(Block Mutable tag es)
σ
[]
(Val $ ValLoc l)
(state_alloc l (Header tag (length es)) vs σ)
[]
| base_step_block_immutable_nongenerative tag es vs σ :
es = of_vals vs →
base_step
tid
(Block ImmutableNongenerative tag es)
σ
[]
(Val $ ValBlock Nongenerative tag vs)
σ
[]
| base_step_block_immutable_generative_weak tag es vs σ :
es = of_vals vs →
base_step
tid
(Block ImmutableGenerativeWeak tag es)
σ
[]
(Val $ ValBlock (Generative None) tag vs)
σ
[]
| base_step_block_immutable_generative_strong tag es vs σ bid :
es = of_vals vs →
base_step
tid
(Block ImmutableGenerativeStrong tag es)
σ
[]
(Val $ ValBlock (Generative (Some bid)) tag vs)
σ
[]
| base_step_match_mutable l hdr x e brs e' σ :
σ.(state_headers) !! l = Some hdr →
eval_match hdr.(header_tag) hdr.(header_size) (SubjectLoc l) x e brs = Some e' →
base_step
tid
(Match (Val $ ValLoc l) x e brs)
σ
[]
e'
σ
[]
| base_step_match_immutable gen tag vs x e brs e' σ :
eval_match tag (length vs) (SubjectBlock gen vs) x e brs = Some e' →
base_step
tid
(Match (Val $ ValBlock gen tag vs) x e brs)
σ
[]
e'
σ
[]
| base_step_get_tag_mutable l hdr σ :
σ.(state_headers) !! l = Some hdr →
base_step
tid
(GetTag $ Val $ ValLoc l)
σ
[]
(Val $ ValNat (encode_tag hdr.(header_tag)))
σ
[]
| base_step_get_tag_immutable gen tag vs σ :
0 < length vs →
base_step
tid
(GetTag $ Val $ ValBlock gen tag vs)
σ
[]
(Val $ ValNat (encode_tag tag))
σ
[]
| base_step_get_size_mutable l hdr σ :
σ.(state_headers) !! l = Some hdr →
base_step
tid
(GetSize $ Val $ ValLoc l)
σ
[]
(Val $ ValNat hdr.(header_size))
σ
[]
| base_step_get_size_immutable gen tag vs σ :
0 < length vs →
base_step
tid
(GetSize $ Val $ ValBlock gen tag vs)
σ
[]
(Val $ ValNat (length vs))
σ
[]
| base_step_get_field_mutable l fld v σ :
σ.(state_heap) !! (l +ₗ fld) = Some v →
base_step
tid
(Load (Val $ ValLoc l) (Val $ ValInt fld))
σ
[]
(Val v)
σ
[]
| base_step_get_field_immutable gen tag vs (fld : nat) v σ :
vs !! fld = Some v →
base_step
tid
(Load (Val $ ValBlock gen tag vs) (Val $ ValNat fld))
σ
[]
(Val v)
σ
[]
| base_step_set_field l fld v σ :
is_Some (σ.(state_heap) !! (l +ₗ fld)) →
base_step
tid
(Store (Val $ ValLoc l) (Val $ ValInt fld) (Val v))
σ
[]
Unit
(state_set_location (l +ₗ fld) v σ)
[]
| base_step_xchg l fld v w σ :
σ.(state_heap) !! (l +ₗ fld) = Some w →
base_step
tid
(Xchg (Val $ ValTuple [ValLoc l; ValInt fld]) (Val v))
σ
[]
(Val w)
(state_set_location (l +ₗ fld) v σ)
[]
| base_step_cas_fail l fld v1 v2 v σ :
σ.(state_heap) !! (l +ₗ fld) = Some v →
v ≉ v1 →
base_step
tid
(CAS (Val $ ValTuple [ValLoc l; ValInt fld]) (Val v1) (Val v2))
σ
[]
(Val $ ValBool false)
σ
[]
| base_step_cas_success l fld v1 v2 v σ :
σ.(state_heap) !! (l +ₗ fld) = Some v →
v ≈ v1 →
base_step
tid
(CAS (Val $ ValTuple [ValLoc l; ValInt fld]) (Val v1) (Val v2))
σ
[]
(Val $ ValBool true)
(state_set_location (l +ₗ fld) v2 σ)
[]
| base_step_faa l fld n m σ :
σ.(state_heap) !! (l +ₗ fld) = Some $ ValInt m →
base_step
tid
(FAA (Val $ ValTuple [ValLoc l; ValInt fld]) (Val $ ValInt n))
σ
[]
(Val $ ValInt m)
(state_set_location (l +ₗ fld) (ValInt (m + n)) σ)
[]
| base_step_fork e σ v :
val_immediate v →
base_step
tid
(Fork e)
σ
[]
Unit
(state_add_local v σ)
[e]
| base_step_get_local v σ :
σ.(state_locals) !! tid = Some v →
base_step
tid
GetLocal
σ
[]
(Val v)
σ
[]
| base_step_set_local v σ :
is_Some (σ.(state_locals) !! tid) →
base_step
tid
(SetLocal (Val v))
σ
[]
Unit
(state_set_local tid v σ)
[]
| base_step_proph σ pid :
pid ∉ σ.(state_prophets) →
base_step
tid
Proph
σ
[]
(Val $ ValProph pid)
(state_add_prophet pid σ)
[]
| base_step_resolve e pid v σ κ w σ' es :
base_step tid e σ κ (Val w) σ' es →
base_step
tid
(Resolve e (Val $ ValProph pid) (Val v))
σ
(κ ++ [(pid, (w, v))])
(Val w)
σ'
es.
Lemma base_step_alloc' tid tag n σ :
let l := location_fresh (dom σ.(state_headers) ∪ dom σ.(state_heap)) in
(0 ≤ n)%Z →
base_step
tid
(Alloc (Val $ ValNat tag) (Val $ ValInt n))
σ
[]
(Val $ ValLoc l)
(state_alloc l (Header tag ₊n) (replicate ₊n ValUnit) σ)
[].
Lemma base_step_block_mutable' tid tag es vs σ :
let l := location_fresh (dom σ.(state_headers) ∪ dom σ.(state_heap)) in
0 < length es →
es = of_vals vs →
base_step
tid
(Block Mutable tag es)
σ
[]
(Val $ ValLoc l)
(state_alloc l (Header tag (length es)) vs σ)
[].
Lemma base_step_block_immutable_generative_strong' tid tag es vs σ :
es = of_vals vs →
base_step
tid
(Block ImmutableGenerativeStrong tag es)
σ
[]
(Val $ ValBlock (Generative (Some inhabitant)) tag vs)
σ
[].
Lemma base_step_fork' tid e σ :
base_step
tid
(Fork e)
σ
[]
Unit
(state_add_local inhabitant σ)
[e].
Lemma base_step_proph' tid σ :
let pid := fresh σ.(state_prophets) in
base_step
tid
Proph
σ
[]
(Val $ ValProph pid)
(state_add_prophet pid σ)
[].
Inductive ectxi :=
| CtxApp1 v2
| CtxApp2 e1
| CtxLet x e2
| CtxUnop (op : unop)
| CtxBinop1 (op : binop) v2
| CtxBinop2 (op : binop) e1
| CtxEqual1 v2
| CtxEqual2 e1
| CtxIf e1 e2
| CtxFor1 e2 e3
| CtxFor2 v1 e3
| CtxAlloc1 v2
| CtxAlloc2 e1
| CtxBlock mut tag es vs
| CtxMatch x e1 brs
| CtxGetTag
| CtxGetSize
| CtxLoad1 v2
| CtxLoad2 e1
| CtxStore1 v2 v3
| CtxStore2 e1 v3
| CtxStore3 e1 e2
| CtxXchg1 v2
| CtxXchg2 e1
| CtxCAS0 v1 v2
| CtxCAS1 e0 v2
| CtxCAS2 e0 e1
| CtxFAA1 v2
| CtxFAA2 e1
| CtxSetLocal
| CtxResolve0 (k : ectxi) v1 v2
| CtxResolve1 e0 v2
| CtxResolve2 e0 e1.
Implicit Types k : ectxi.
Notation CtxSeq := (
CtxLet BAnon
)(only parsing
).
Notation CtxTuple := (
CtxBlock ImmutableNongenerative 0
)(only parsing
).
Fixpoint filli k e : expr :=
match k with
| CtxApp1 v2 ⇒
App e $ Val v2
| CtxApp2 e1 ⇒
App e1 e
| CtxLet x e2 ⇒
Let x e e2
| CtxUnop op ⇒
Unop op e
| CtxBinop1 op v2 ⇒
Binop op e $ Val v2
| CtxBinop2 op e1 ⇒
Binop op e1 e
| CtxEqual1 v2 ⇒
Equal e $ Val v2
| CtxEqual2 e1 ⇒
Equal e1 e
| CtxIf e1 e2 ⇒
If e e1 e2
| CtxFor1 e2 e3 ⇒
For e e2 e3
| CtxFor2 v1 e3 ⇒
For (Val v1) e e3
| CtxAlloc1 v2 ⇒
Alloc e $ Val v2
| CtxAlloc2 e1 ⇒
Alloc e1 e
| CtxBlock mut tag es vs ⇒
Block mut tag $ es ++ e :: of_vals vs
| CtxMatch x e1 brs ⇒
Match e x e1 brs
| CtxGetTag ⇒
GetTag e
| CtxGetSize ⇒
GetSize e
| CtxLoad1 v2 ⇒
Load e (Val v2)
| CtxLoad2 e1 ⇒
Load e1 e
| CtxStore1 v2 v3 ⇒
Store e (Val v2) (Val v3)
| CtxStore2 e1 v3 ⇒
Store e1 e (Val v3)
| CtxStore3 e1 e2 ⇒
Store e1 e2 e
| CtxXchg1 v2 ⇒
Xchg e $ Val v2
| CtxXchg2 e1 ⇒
Xchg e1 e
| CtxCAS0 v1 v2 ⇒
CAS e (Val v1) (Val v2)
| CtxCAS1 e0 v2 ⇒
CAS e0 e $ Val v2
| CtxCAS2 e0 e1 ⇒
CAS e0 e1 e
| CtxFAA1 v2 ⇒
FAA e $ Val v2
| CtxFAA2 e1 ⇒
FAA e1 e
| CtxSetLocal ⇒
SetLocal e
| CtxResolve0 k v1 v2 ⇒
Resolve (filli k e) (Val v1) (Val v2)
| CtxResolve1 e0 v2 ⇒
Resolve e0 e $ Val v2
| CtxResolve2 e0 e1 ⇒
Resolve e0 e1 e
end.
#[global] Arguments filli !_ _ / : assert.
Definition ectx :=
list ectxi.
Definition fill K e :=
foldl (flip filli) e K.
Definition config : Type :=
list expr × state.
gmap.
From zoo Require Import
prelude.
From zoo.language Require Export
physical_equality
metatheory
state.
From zoo Require Import
options.
Implicit Types b : bool.
Implicit Types tag : nat.
Implicit Types n m : Z.
Implicit Types l : location.
Implicit Types gen : generativity.
Implicit Types mut : mutability.
Implicit Types lit : literal.
Implicit Types x : binder.
Implicit Types e : expr.
Implicit Types es : list expr.
Implicit Types v w : val.
Implicit Types vs : list val.
Implicit Types br : branch.
Implicit Types brs : list branch.
Implicit Types rec : recursive.
Implicit Types recs : list recursive.
Definition thread_id :=
nat.
Implicit Types tid : thread_id.
Parameter encode_tag : nat → nat.
Axiom encode_tag_inj :
Inj (=) (=) encode_tag.
#[global] Existing Instance encode_tag_inj.
Definition val_immediate v :=
match v with
| ValLit lit ⇒
match lit with
| LitBool _
| LitInt _ ⇒
true
| _ ⇒
false
end
| ValRecs _ _ ⇒
false
| ValBlock _ _ [] ⇒
true
| ValBlock _ _ _ ⇒
false
end.
#[global] Arguments val_immediate !_ / : assert.
Definition eval_unop op v :=
match op, v with
| UnopNeg, ValBool b ⇒
Some $ ValBool (¬ b)
| UnopMinus, ValInt n ⇒
Some $ ValInt (- n)
| UnopIsImmediate, v ⇒
Some $ ValBool (val_immediate v)
| _, _ ⇒
None
end.
#[global] Arguments eval_unop !_ !_ / : assert.
Definition eval_binop_int op n1 n2 :=
match op with
| BinopPlus ⇒
LitInt (n1 + n2)
| BinopMinus ⇒
LitInt (n1 - n2)
| BinopMult ⇒
LitInt (n1 × n2)
| BinopQuot ⇒
LitInt (n1 `quot` n2)
| BinopRem ⇒
LitInt (n1 `rem` n2)
| BinopLand ⇒
LitInt (Z.land n1 n2)
| BinopLor ⇒
LitInt (Z.lor n1 n2)
| BinopLsl ⇒
LitInt (n1 ≪ n2)
| BinopLsr ⇒
LitInt (n1 ≫ n2)
| BinopLe ⇒
LitBool (bool_decide (n1 ≤ n2))
| BinopLt ⇒
LitBool (bool_decide (n1 < n2))
| BinopGe ⇒
LitBool (bool_decide (n1 ≥ n2))
| BinopGt ⇒
LitBool (bool_decide (n1 > n2))
end%Z.
#[global] Arguments eval_binop_int !_ _ _ / : assert.
Definition eval_binop op v1 v2 :=
match v1, v2 with
| ValInt n1, ValInt n2 ⇒
Some $ ValLit $ eval_binop_int op n1 n2
| _, _ ⇒
None
end.
#[global] Arguments eval_binop _ !_ !_ / : assert.
Definition eval_app_aux recs i rec :=
subst' rec.1.1 (ValRecs i recs).
Definition eval_app' {A} foldri recs x v e : A :=
foldri (eval_app_aux recs) (subst' x v e).
Definition eval_app recs x v e :=
eval_app' foldri recs x v e recs.
Variant subject :=
| SubjectLoc l
| SubjectBlock gen vs.
Implicit Types subj : subject.
Definition subject_to_val tag subj :=
match subj with
| SubjectLoc l ⇒
ValLoc l
| SubjectBlock gen vs ⇒
ValBlock gen tag vs
end.
Fixpoint eval_match tag sz subj x_fb e_fb brs :=
match brs with
| [] ⇒
Some $ subst' x_fb (subject_to_val tag subj) e_fb
| br :: brs ⇒
let pat := br.1 in
if pat.(pattern_tag) ≟ tag && length pat.(pattern_fields) ≟ sz then
let res := subst' pat.(pattern_as) (subject_to_val tag subj) br.2 in
match subj with
| SubjectLoc l ⇒
if forallb (BAnon ≟.) pat.(pattern_fields) then
Some res
else
None
| SubjectBlock _ vs ⇒
Some $ subst_list pat.(pattern_fields) vs res
end
else
eval_match tag sz subj x_fb e_fb brs
end.
#[global] Arguments eval_match _ _ !_ _ _ !_ / : assert.
Definition observation : Set :=
prophet_id × (val × val).
Inductive base_step tid : expr → state → list observation → expr → state → list expr → Prop :=
| base_step_rec f x e σ :
base_step
tid
(Rec f x e)
σ
[]
(Val $ ValRec f x e)
σ
[]
| base_step_app i recs rec v σ :
recs !! i = Some rec →
base_step
tid
(App (Val $ ValRecs i recs) (Val v))
σ
[]
(eval_app recs rec.1.2 v rec.2)
σ
[]
| base_step_let x v1 e2 σ :
base_step
tid
(Let x (Val v1) e2)
σ
[]
(subst' x v1 e2)
σ
[]
| base_step_unop op v v' σ :
eval_unop op v = Some v' →
base_step
tid
(Unop op $ Val v)
σ
[]
(Val v')
σ
[]
| base_step_binop op v1 v2 v' σ :
eval_binop op v1 v2 = Some v' →
base_step
tid
(Binop op (Val v1) (Val v2))
σ
[]
(Val v')
σ
[]
| base_step_equal_fail v1 v2 σ :
v1 ≉ v2 →
base_step
tid
(Equal (Val v1) (Val v2))
σ
[]
(Val $ ValBool false)
σ
[]
| base_step_equal_success v1 v2 σ :
v1 ≈ v2 →
base_step
tid
(Equal (Val v1) (Val v2))
σ
[]
(Val $ ValBool true)
σ
[]
| base_step_if b e1 e2 σ :
base_step
tid
(If (Val $ ValBool b) e1 e2)
σ
[]
(if b then e1 else e2)
σ
[]
| base_step_for n1 n2 e σ :
base_step
tid
(For (Val $ ValInt n1) (Val $ ValInt n2) e)
σ
[]
(if decide (n2 ≤ n1)%Z then Unit else Seq (App e (Val $ ValInt n1)) (For (Val $ ValInt (n1 + 1)) (Val $ ValInt n2) e))
σ
[]
| base_step_alloc tag n σ l :
(0 ≤ n)%Z →
σ.(state_headers) !! l = None →
( ∀ i,
i < ₊n →
σ.(state_headers) !! (l +ₗ i) = None ∧
σ.(state_heap) !! (l +ₗ i) = None
) →
base_step
tid
(Alloc (Val $ ValNat tag) (Val $ ValInt n))
σ
[]
(Val $ ValLoc l)
(state_alloc l (Header tag ₊n) (replicate ₊n ValUnit) σ)
[]
| base_step_block_mutable tag es vs σ l :
0 < length es →
es = of_vals vs →
σ.(state_headers) !! l = None →
( ∀ i,
i < length es →
σ.(state_headers) !! (l +ₗ i) = None ∧
σ.(state_heap) !! (l +ₗ i) = None
) →
base_step
tid
(Block Mutable tag es)
σ
[]
(Val $ ValLoc l)
(state_alloc l (Header tag (length es)) vs σ)
[]
| base_step_block_immutable_nongenerative tag es vs σ :
es = of_vals vs →
base_step
tid
(Block ImmutableNongenerative tag es)
σ
[]
(Val $ ValBlock Nongenerative tag vs)
σ
[]
| base_step_block_immutable_generative_weak tag es vs σ :
es = of_vals vs →
base_step
tid
(Block ImmutableGenerativeWeak tag es)
σ
[]
(Val $ ValBlock (Generative None) tag vs)
σ
[]
| base_step_block_immutable_generative_strong tag es vs σ bid :
es = of_vals vs →
base_step
tid
(Block ImmutableGenerativeStrong tag es)
σ
[]
(Val $ ValBlock (Generative (Some bid)) tag vs)
σ
[]
| base_step_match_mutable l hdr x e brs e' σ :
σ.(state_headers) !! l = Some hdr →
eval_match hdr.(header_tag) hdr.(header_size) (SubjectLoc l) x e brs = Some e' →
base_step
tid
(Match (Val $ ValLoc l) x e brs)
σ
[]
e'
σ
[]
| base_step_match_immutable gen tag vs x e brs e' σ :
eval_match tag (length vs) (SubjectBlock gen vs) x e brs = Some e' →
base_step
tid
(Match (Val $ ValBlock gen tag vs) x e brs)
σ
[]
e'
σ
[]
| base_step_get_tag_mutable l hdr σ :
σ.(state_headers) !! l = Some hdr →
base_step
tid
(GetTag $ Val $ ValLoc l)
σ
[]
(Val $ ValNat (encode_tag hdr.(header_tag)))
σ
[]
| base_step_get_tag_immutable gen tag vs σ :
0 < length vs →
base_step
tid
(GetTag $ Val $ ValBlock gen tag vs)
σ
[]
(Val $ ValNat (encode_tag tag))
σ
[]
| base_step_get_size_mutable l hdr σ :
σ.(state_headers) !! l = Some hdr →
base_step
tid
(GetSize $ Val $ ValLoc l)
σ
[]
(Val $ ValNat hdr.(header_size))
σ
[]
| base_step_get_size_immutable gen tag vs σ :
0 < length vs →
base_step
tid
(GetSize $ Val $ ValBlock gen tag vs)
σ
[]
(Val $ ValNat (length vs))
σ
[]
| base_step_get_field_mutable l fld v σ :
σ.(state_heap) !! (l +ₗ fld) = Some v →
base_step
tid
(Load (Val $ ValLoc l) (Val $ ValInt fld))
σ
[]
(Val v)
σ
[]
| base_step_get_field_immutable gen tag vs (fld : nat) v σ :
vs !! fld = Some v →
base_step
tid
(Load (Val $ ValBlock gen tag vs) (Val $ ValNat fld))
σ
[]
(Val v)
σ
[]
| base_step_set_field l fld v σ :
is_Some (σ.(state_heap) !! (l +ₗ fld)) →
base_step
tid
(Store (Val $ ValLoc l) (Val $ ValInt fld) (Val v))
σ
[]
Unit
(state_set_location (l +ₗ fld) v σ)
[]
| base_step_xchg l fld v w σ :
σ.(state_heap) !! (l +ₗ fld) = Some w →
base_step
tid
(Xchg (Val $ ValTuple [ValLoc l; ValInt fld]) (Val v))
σ
[]
(Val w)
(state_set_location (l +ₗ fld) v σ)
[]
| base_step_cas_fail l fld v1 v2 v σ :
σ.(state_heap) !! (l +ₗ fld) = Some v →
v ≉ v1 →
base_step
tid
(CAS (Val $ ValTuple [ValLoc l; ValInt fld]) (Val v1) (Val v2))
σ
[]
(Val $ ValBool false)
σ
[]
| base_step_cas_success l fld v1 v2 v σ :
σ.(state_heap) !! (l +ₗ fld) = Some v →
v ≈ v1 →
base_step
tid
(CAS (Val $ ValTuple [ValLoc l; ValInt fld]) (Val v1) (Val v2))
σ
[]
(Val $ ValBool true)
(state_set_location (l +ₗ fld) v2 σ)
[]
| base_step_faa l fld n m σ :
σ.(state_heap) !! (l +ₗ fld) = Some $ ValInt m →
base_step
tid
(FAA (Val $ ValTuple [ValLoc l; ValInt fld]) (Val $ ValInt n))
σ
[]
(Val $ ValInt m)
(state_set_location (l +ₗ fld) (ValInt (m + n)) σ)
[]
| base_step_fork e σ v :
val_immediate v →
base_step
tid
(Fork e)
σ
[]
Unit
(state_add_local v σ)
[e]
| base_step_get_local v σ :
σ.(state_locals) !! tid = Some v →
base_step
tid
GetLocal
σ
[]
(Val v)
σ
[]
| base_step_set_local v σ :
is_Some (σ.(state_locals) !! tid) →
base_step
tid
(SetLocal (Val v))
σ
[]
Unit
(state_set_local tid v σ)
[]
| base_step_proph σ pid :
pid ∉ σ.(state_prophets) →
base_step
tid
Proph
σ
[]
(Val $ ValProph pid)
(state_add_prophet pid σ)
[]
| base_step_resolve e pid v σ κ w σ' es :
base_step tid e σ κ (Val w) σ' es →
base_step
tid
(Resolve e (Val $ ValProph pid) (Val v))
σ
(κ ++ [(pid, (w, v))])
(Val w)
σ'
es.
Lemma base_step_alloc' tid tag n σ :
let l := location_fresh (dom σ.(state_headers) ∪ dom σ.(state_heap)) in
(0 ≤ n)%Z →
base_step
tid
(Alloc (Val $ ValNat tag) (Val $ ValInt n))
σ
[]
(Val $ ValLoc l)
(state_alloc l (Header tag ₊n) (replicate ₊n ValUnit) σ)
[].
Lemma base_step_block_mutable' tid tag es vs σ :
let l := location_fresh (dom σ.(state_headers) ∪ dom σ.(state_heap)) in
0 < length es →
es = of_vals vs →
base_step
tid
(Block Mutable tag es)
σ
[]
(Val $ ValLoc l)
(state_alloc l (Header tag (length es)) vs σ)
[].
Lemma base_step_block_immutable_generative_strong' tid tag es vs σ :
es = of_vals vs →
base_step
tid
(Block ImmutableGenerativeStrong tag es)
σ
[]
(Val $ ValBlock (Generative (Some inhabitant)) tag vs)
σ
[].
Lemma base_step_fork' tid e σ :
base_step
tid
(Fork e)
σ
[]
Unit
(state_add_local inhabitant σ)
[e].
Lemma base_step_proph' tid σ :
let pid := fresh σ.(state_prophets) in
base_step
tid
Proph
σ
[]
(Val $ ValProph pid)
(state_add_prophet pid σ)
[].
Inductive ectxi :=
| CtxApp1 v2
| CtxApp2 e1
| CtxLet x e2
| CtxUnop (op : unop)
| CtxBinop1 (op : binop) v2
| CtxBinop2 (op : binop) e1
| CtxEqual1 v2
| CtxEqual2 e1
| CtxIf e1 e2
| CtxFor1 e2 e3
| CtxFor2 v1 e3
| CtxAlloc1 v2
| CtxAlloc2 e1
| CtxBlock mut tag es vs
| CtxMatch x e1 brs
| CtxGetTag
| CtxGetSize
| CtxLoad1 v2
| CtxLoad2 e1
| CtxStore1 v2 v3
| CtxStore2 e1 v3
| CtxStore3 e1 e2
| CtxXchg1 v2
| CtxXchg2 e1
| CtxCAS0 v1 v2
| CtxCAS1 e0 v2
| CtxCAS2 e0 e1
| CtxFAA1 v2
| CtxFAA2 e1
| CtxSetLocal
| CtxResolve0 (k : ectxi) v1 v2
| CtxResolve1 e0 v2
| CtxResolve2 e0 e1.
Implicit Types k : ectxi.
Notation CtxSeq := (
CtxLet BAnon
)(only parsing
).
Notation CtxTuple := (
CtxBlock ImmutableNongenerative 0
)(only parsing
).
Fixpoint filli k e : expr :=
match k with
| CtxApp1 v2 ⇒
App e $ Val v2
| CtxApp2 e1 ⇒
App e1 e
| CtxLet x e2 ⇒
Let x e e2
| CtxUnop op ⇒
Unop op e
| CtxBinop1 op v2 ⇒
Binop op e $ Val v2
| CtxBinop2 op e1 ⇒
Binop op e1 e
| CtxEqual1 v2 ⇒
Equal e $ Val v2
| CtxEqual2 e1 ⇒
Equal e1 e
| CtxIf e1 e2 ⇒
If e e1 e2
| CtxFor1 e2 e3 ⇒
For e e2 e3
| CtxFor2 v1 e3 ⇒
For (Val v1) e e3
| CtxAlloc1 v2 ⇒
Alloc e $ Val v2
| CtxAlloc2 e1 ⇒
Alloc e1 e
| CtxBlock mut tag es vs ⇒
Block mut tag $ es ++ e :: of_vals vs
| CtxMatch x e1 brs ⇒
Match e x e1 brs
| CtxGetTag ⇒
GetTag e
| CtxGetSize ⇒
GetSize e
| CtxLoad1 v2 ⇒
Load e (Val v2)
| CtxLoad2 e1 ⇒
Load e1 e
| CtxStore1 v2 v3 ⇒
Store e (Val v2) (Val v3)
| CtxStore2 e1 v3 ⇒
Store e1 e (Val v3)
| CtxStore3 e1 e2 ⇒
Store e1 e2 e
| CtxXchg1 v2 ⇒
Xchg e $ Val v2
| CtxXchg2 e1 ⇒
Xchg e1 e
| CtxCAS0 v1 v2 ⇒
CAS e (Val v1) (Val v2)
| CtxCAS1 e0 v2 ⇒
CAS e0 e $ Val v2
| CtxCAS2 e0 e1 ⇒
CAS e0 e1 e
| CtxFAA1 v2 ⇒
FAA e $ Val v2
| CtxFAA2 e1 ⇒
FAA e1 e
| CtxSetLocal ⇒
SetLocal e
| CtxResolve0 k v1 v2 ⇒
Resolve (filli k e) (Val v1) (Val v2)
| CtxResolve1 e0 v2 ⇒
Resolve e0 e $ Val v2
| CtxResolve2 e0 e1 ⇒
Resolve e0 e1 e
end.
#[global] Arguments filli !_ _ / : assert.
Definition ectx :=
list ectxi.
Definition fill K e :=
foldl (flip filli) e K.
Definition config : Type :=
list expr × state.