Newer
Older
Module Type CORE_LANG.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
Delimit Scope lang_scope with lang.
Local Open Scope lang_scope.
(******************************************************************)
(** ** Syntax, machine state, and atomic reductions **)
(******************************************************************)
(** Expressions and values **)
Parameter expr : Type.
Parameter is_value : expr -> Prop.
Definition value : Type := {e: expr | is_value e}.
Parameter is_value_dec : forall e, is_value e + ~is_value e.
(* fork and fRet *)
Parameter fork : expr -> expr.
Parameter fork_ret : expr.
Axiom fork_ret_is_value : is_value fork_ret.
Definition fork_ret_val : value := exist _ fork_ret fork_ret_is_value.
Axiom fork_not_value : forall e,
~is_value (fork e).
Axiom fork_inj : forall e1 e2,
fork e1 = fork e2 -> e1 = e2.
(** Evaluation contexts **)
Parameter ectx : Type.
Parameter empty_ctx : ectx.
Parameter comp_ctx : ectx -> ectx -> ectx.
Parameter fill : ectx -> expr -> expr.
Notation "'ε'" := empty_ctx : lang_scope.
Notation "K1 ∘ K2" := (comp_ctx K1 K2) (at level 40, left associativity) : lang_scope.
Notation "K '[[' e ']]' " := (fill K e) (at level 40, left associativity) : lang_scope.
Axiom fill_empty : forall e, ε [[ e ]] = e.
Axiom fill_comp : forall K1 K2 e, K1 [[ K2 [[ e ]] ]] = K1 ∘ K2 [[ e ]].
Axiom fill_inj1 : forall K1 K2 e,
K1 [[ e ]] = K2 [[ e ]] -> K1 = K2.
Axiom fill_inj2 : forall K e1 e2,
K [[ e1 ]] = K [[ e2 ]] -> e1 = e2.
Axiom fill_noinv: forall K1 K2, (* Interestingly, it seems impossible to derive this *)
K1 ∘ K2 = ε -> K1 = ε /\ K2 = ε.
Axiom fill_value : forall K e,
is_value (K [[ e ]]) ->
K = ε.
Axiom fill_fork : forall K e e',
fork e' = K [[ e ]] ->
K = ε.
(** Shared machine state (e.g., the heap) **)
Parameter state : Type.
(** Primitive (single thread) machine configurations **)
Definition prim_cfg : Type := (expr * state)%type.
(** The primitive atomic stepping relation **)
Parameter prim_step : prim_cfg -> prim_cfg -> Prop.
Definition reducible e: Prop :=
exists sigma cfg', prim_step (e, sigma) cfg'.
Definition stuck (e : expr) : Prop :=
e = K [[ e' ]] ->
Axiom fork_stuck :
forall K e, stuck (K [[ fork e ]]).
Axiom values_stuck :
forall e, is_value e -> stuck e.
(* 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
sub-context of K' - in other words, e also contains the reducible
expression *)
Axiom step_by_value :
K [[ e ]] = K' [[ e' ]] ->
~ is_value e ->
exists K'', K' = K ∘ K''.
(* Similar to above, buth with a fork instead of a reducible
expression *)
Axiom fork_by_value :
forall K K' e e',
K [[ e ]] = K' [[ fork e' ]] ->
~ is_value e ->
exists K'', K' = K ∘ K''.
(** Atomic expressions **)
Parameter atomic : expr -> Prop.
Axiom atomic_reducible :
forall e, atomic e -> reducible e.
Axiom atomic_step: forall e σ e' σ',
atomic e ->
prim_step (e, σ) (e', σ') ->
is_value e'.
End CORE_LANG.