In this file we pull everything together and define evaluation structures and the abstract characterization of a language machine, together with all the associated laws.
Note that we have here a minor mismatch between the formalization and the paper: we have realized a posteriori a more elegant way to decompose the abstract machine as exposed in the paper.
Here, instead of only requiring an embedding of normal forms into configurations (refold, from Def. 11), we require an observation application function oapp describing how to build a configuration from a value, an observation, and an assignment. Since normal forms are triples of a variable, an observation and an assignment, the sole difference is in the first component: instead of just a variable, oapp takes any value. Both are easily interdefineable. While refold is more compact to introduce, it is slightly more cumbersome to work with, which is why we axiomatize oapp directly.
Patching the development to follow more closely the paper's presentation would be slightly technical due to the technicality of the mechanized proofs involved, but essentially straightforward.
We here define what is called an evaluation structure in the paper (Def. 11). It tells us how to evaluate a configuration to a normal form and how to stitch one back together from the data sent by Opponent.
Class machine (val : Famβ T C) (conf : Famβ T C) (obs : obs_struct T C) := {
eval : conf ββ (delay β nf obs val) ;
oapp [Ξ x] (v : val Ξ x) (o : obs x) : dom o =[val]> Ξ -> conf Ξ ;
}.
Next we define "evaluating then observing" (Def. 14).
Definition evalβ `{machine val conf obs}
: conf ββ (delay β obsβ) :=
fun _ t => then_to_obs (eval t) .
Notation "v β o β¦ a β¦" := (oapp v o a) (at level 20).
We can readily define the embedding from normal forms to configurations (i.e., we can derive what is called refold in the paper).
Definition emb `{machine val conf obs} {_ : subst_monoid val}
: nf obs val ββ conf
:= fun _ n => oapp (v_var (nf_var n)) (nf_obs n) (nf_args n) .
Next we define the "bad instanciation" relation (Def. 28).
Variant head_inst_nostep `{machine val conf obs} {VM : subst_monoid val}
(u : sigT obs) : sigT obs -> Prop :=
| HeadInst {Ξ y} (v : val Ξ y) (o : obs y) (a : dom o =[val]> Ξ) (i : Ξ β projT1 u)
: Β¬(is_var v)
-> evalβ (v β oβ¦aβ¦) β ret_delay (i β
projT2 u)
-> head_inst_nostep u (y ,' o) .
Finally we define the structure containing all the remaining axioms of a language machine (Def. 13).
Class machine_laws val conf obs {M : machine val conf obs}
{VM : subst_monoid val} {CM : subst_module val conf} := {
oapp respects pointwise equality of assignments.
oapp_proper {Ξ x} {v : val Ξ x} {o} :: Proper (asgn_eq (dom o) Ξ ==> eq) (oapp v o) ;
oapp commutes with substitutions. This is the equivalent of the second equation at the end of Def. 13, in terms of oapp instead of refold.
app_sub {Ξ1 Ξ2 x} (v : val Ξ1 x) (o : obs x) (a : dom o =[val]> Ξ1) (b : Ξ1 =[val]> Ξ2)
: (v β oβ¦aβ¦) ββ b = (v α΅₯β b) β oβ¦a β bβ¦ ;
"evaluation respects substitution". This is the core hypothesis of the OGS soundness, stating essentially "substituting, then evaluating" is equivalent to "evaluating, then substituting, then evaluating once more". It is the equvalent of the first equation at the end of Def. 13.
eval_sub {Ξ Ξ} (c : conf Ξ) (a : Ξ =[val]> Ξ)
: eval (c ββ a) β bind_delay' (eval c) (fun n => eval (emb n ββ a)) ;
Evaluating the embedding of a normal form is equivalent to returning the normal form. This is part of the evaluation structure (Def. 11) in the paper.
eval_nf_ret {Ξ} (u : nf obs val Ξ)
: eval (emb u) β ret_delay u ;
At last the mystery hypothesis, stating that the machine has focused redexes (Def. 28). It is necessary for establishing that the composition can be defined by eventually guarded iteration.
eval_app_not_var : well_founded head_inst_nostep ;
} .
End with_param.
Finally we define a cute notation for applying an observation to a value.
#[global] Notation "v β o β¦ a β¦" := (oapp v o a) (at level 20).