Maxim Koltsov
What is NbE
Terms
Syntax
Normalization
What is NbE
Terms
Denotations
Syntax
Semantics
Evaluation
Reification
Normalization by Evaluation
Question: how to build NbE procedure?
Pick semantics model (= meta language) that makes reification easy
Danvy's Type Directed Partial Evaluation
Terms
a, b, c, x, y, ... : variables \x -> t: lambda-abstractions a b: application <t1, t2>: pairs p1 t, p2 t: projections
Danvy's Type Directed Partial Evaluation
reify_t : D -> Normal terms
Let D be some model
reify_o t = t, for o — atomic type reify_(a -> b) t = \x -> reify_b (t (reflect_a x)) reify_(<a, b>) t = <p1 (reify_a t), p2 (reify_b t)>
reflect_o t = t, for o — atomic type reflect_(a -> b) t = fun(s) { reflect_b (t (reify_a s)) } reflect_(<a, b>) t = (reflect_a (p1 t), reflect_b (p2 t))
reflect_t : Neutral terms -> D
So, model (D) must support variables, functions and pairs
In Haskell it may be:
data Ty
= Int
| Fun Ty Ty
deriving (Eq, Show)
data Term
= Var String
| VInt Int
| Lam String Term
| App Term Term
| Pair Term Term
| P1 Term
| P2 Term
deriving (Eq, Show)
-- | Semantics of terms
data Sem
= SNeu Term
-- ^ neutral: only atomic types and applications
| SFun (Sem -> Sem)
| SPair Sem Sem
Can we add sums?
Terms:
Left t, Right t case t of (Left x -> t, Right x -> t)
reflect_(Either a b) t = case t of ...
NO — we need more complicated model and meta-language
Danvy: shift/reset
NbE and calculus properties
Soundness: if \( \Gamma \vdash p : A \), then in a model where \( \Gamma \) holds, \( A \) holds
\( \Gamma \vdash p : A \) — proof of proposition A under hypotheses Г (Curry-Howard)
Completeness: if in any model Г implies A, then there exists term \( p \) such that \( Г \vdash p : A \)
\( Г \vdash p : A \to (w \Vdash Г => w \Vdash A) \)
\( (\forall w.\ w \Vdash Г \to w \Vdash A) \to Г \vdash p : A \)
Evaluation
Reification
Ilik's CPS model
Key ideas:
Kripke model for lambda calculus
\( (K, \leq) \) — preorder of possible worlds
Relation of forcing: for world w in K and n-ary predicate X, \( w \Vdash X \) — n-ary relation on w, such that
For \( w' \geq w \), \( (w \Vdash X)(d_1, \ldots, d_n) \to (w', \Vdash X)(d_1, \ldots, d_n) \)
For compound propositions (= types):
\( w \Vdash A \to B \) means for all \( w' \ge w \) \( w' \Vdash A \) implies \( w' \Vdash B \)
\( w \Vdash <A, B> \) means \( w \Vdash A \) AND \(w \Vdash B \)
\( w \Vdash \text{Either}(A, B) \) means \( w \Vdash A \) OR \(w \Vdash B \)
Again, meta language must have functions, pairs and sums
Soundness: If \( \Gamma \vdash p:A \), then in any model for any world, if \( w \Vdash \Gamma \), then \( w \Vdash A \)
Completeness: if in any model, in any world \( w \Vdash \Gamma \) implies \( w \Vdash A \), then there exists a term \( p \) such that \( \Gamma \vdash p:A \)
We can construct an Universal Model for proving completeness
Universal model
\( K \) (possible worlds) will be a set of different contexts \( \Gamma \)
\( \Gamma \leq \Gamma' \) if \( \Gamma \subseteq \Gamma' \)
Forcing: \( \Gamma \Vdash A \) — a set of normal form derivations \( \Gamma \vdash^{nf} A \), where \( A \) — closed and atomic
Then, for example, by definition
\( \Gamma \Vdash A \to B \) when for all \( \Gamma' \geq \Gamma \) \(\Gamma' \vdash^{nf} A \) implies \( \Gamma' \vdash^{nf} B \) — a function in meta-language
Kripke model for logic with sums
New binary relation: \( w \Vdash_\bot^C \) — world is exploding at formula \( C \)
Strong forcing \( w \Vdash_s A \) defined as before for atomic formulas
Non-strong forcing: \( w \Vdash A \) if
$$ \forall C\, \forall w' \geq w \left( \forall w'' \geq w'\, w'' \Vdash_s A \to w'' \Vdash_\bot^C \right) \to w' \Vdash_\bot^C $$
Extend strong forcing to all formulas:
Universal model for Kripke model with sums
Forcing:
$$ \forall C\, \forall \Gamma' \geq \Gamma \left( \forall \Gamma'' \geq \Gamma'\, \Gamma'' \Vdash_s A \to \Gamma'' \vdash^{nf} C \right) \to \Gamma' \vdash^{nf} C $$
In Haskell:
data Sem
= Sem ((StrongForcing -> Term) -> Term)
data StrongForcing
= FInt Term
| FPair Sem Sem
| FSum (Either Sem Sem)
| FFun (Sem -> Sem)
Reification
"unit": \( \eta: w \Vdash_s A \to w \Vdash A \), \( \eta(a) = \lambda k.\, k a \)
"bind": \( * : (\forall w' \geq w\, w' \Vdash_s A \to w' \Vdash B) \to w \Vdash A \to w \Vdash B \),
\(\phi*a = \lambda k.\, a\ (\lambda b.\, \phi\ b\ k) \)
Forcing (\( w \Vdash A \)) is kinda "Cont" monad storing strong forcing (\( w \Vdash_s A \))
"run": \( \mu : w \Vdash X \to w \Vdash_s X \) for atomic \( X \), by definition of \( \Vdash \)
Reification
reify_X (a) = \( \mu(a) \), \(X\) — atomic
reify_(A->B) (f) = \( \eta\left(\lambda s.\, \lambda x.\, \text{reify}_B (s (\text{reflect}_A x))\right) \)
reify_(Either A B) (a) =
$$ \eta\left( \lambda s.\, (\text{Left}\ l \to \text{reify}_A l; \text{Right}\ r \to \text{reify}_B r)\right) $$
reflect_X (a) = \( \eta(a) \), \( X \) — atomic
reflect_(A->B) (f) = \( \eta\left( \lambda x.\, \text{reflect}_B (f (\text{reify}_A x)) \right) \)
reflect_(Either A B) (t) =
$$ \lambda k.\, \text{case}\ t\ \text{of}\ \Bigl[\text{Left}\ l \to k (\text{Left}\ (\text{reflect}_A l));$$
$$ \text{Right}\ r \to k (\text{Right}\ (\text{reflect}_B r)) \Bigr]$$
Examples
t :: Either Church () -> Church -> Church
t = \c -> \n0 ->
case c of
Left n -> add n n0
Right _ -> \f -> \x -> f (n0 f x)
nbe(t (Left 3)):
t' :: Church -> Church
t' = \n0 -> \f -> \x -> f $ f $ f (n0 $ \k -> f k) x
nbe(t (Right ())):
t' :: Church -> Church
t' = \n0 -> \f -> \x -> f (n0 $ \k -> f k) x
Modal logic
New type: \( \Box A \)
New terms:
quot t : \(\Box A\) if \( t : A \)
let box u = t in e: A if \( t : \Box A \) and \( \Gamma; \Delta, u:A \vdash e : B \)
Two contexts: \( \Gamma; \Delta \vdash t : A \)
exp :: Int -> [] (Int -> Int)
exp b =
if zero b
then box (\_ -> 1)
else
let box u = exp (b - 1)
in box (\x -> x * (u x))
\x -> let box u = exp 3 in u x :: Int -> Int
Kripke CPS model
Strong forcing:
\( \Gamma; \Delta \Vdash_s \text{box}\ A \) is a pair of \( \Gamma; \emptyset \vdash t \) and \( \Gamma; \Delta \Vdash A \)
eval(box t) = \( \eta( <\text{graft}\ t, \text{eval}\ t>) \)
eval(let box u = t in e) =
$$ \lambda k.\, (\text{eval}\ t) (<t, s> \to (\text{eval}\ b) k) $$
reify([] A)(t) = \( t (<t, s> \to \text{box}\ t) \)
reflect([] A)(t) =
$$ \lambda k.\, \text{let box}\ u = t\ \text{in}\ k <u, \text{reflect}_A u> $$
Example
nbe (exp 3) :: [] (Int -> Int)
nbe (exp 3) = box \x -> x * ( (\y -> y * ((\z -> ...)) y) x)
nbe (exp 3)
Full normalization: nbe(let box u = exp 3 in u)
nbe (let box u = exp 3 in u) :: Int -> Int
\x -> x * x * x * 1
Next steps