BigStep: Big-step semantics of untyped lambda calculus
module plfa.part2.BigStep where
Introduction
The call-by-name evaluation strategy is a deterministic method for computing the value of a program in the lambda calculus. That is, call-by-name produces a value if and only if beta reduction can reduce the program to a lambda abstraction. In this chapter we define call-by-name evaluation and prove the forward direction of this if-and-only-if. The backward direction is traditionally proved via Curry-Feys standardisation, which is quite complex. We give a sketch of that proof, due to Plotkin, but postpone the proof in Agda until after we have developed a denotational semantics for the lambda calculus, at which point the proof is an easy corollary of properties of the denotational semantics.
We present the call-by-name strategy as a relation between an input term and an output value. Such a relation is often called a big-step semantics, written M β V, as it relates the input term M directly to the final result V, in contrast to the small-step reduction relation, M ββ Mβ², that maps M to another term Mβ² in which a single sub-computation has been completed.
Imports
open import Relation.Binary.PropositionalEquality using (_β‘_; refl; trans; sym; cong-app) open import Data.Product.Base using (_Γ_; Ξ£; Ξ£-syntax; β; β-syntax; projβ; projβ) renaming (_,_ to β¨_,_β©) open import Function.Base using (_β_) open import plfa.part2.Untyped using (Context; _β’_; _β_; β ; β ; _,_; Z; S_; `_; #_; Ζ_; _Β·_; subst; subst-zero; exts; rename; Ξ²; ΞΎβ; ΞΎβ; ΞΆ; _ββ_; _ββ _; _βββ¨_β©_; _β; ββ -trans; appL-cong) open import plfa.part2.Substitution using (Subst; ids)
Environments
To handle variables and function applications, there is the choice between using substitution, as in ββ, or to use an environment. An environment in call-by-name is a map from variables to closures, that is, to terms paired with their environments. We choose to use environments instead of substitution because the point of the call-by-name strategy is to be closer to an implementation of the language. Also, the denotational semantics introduced in later chapters uses environments and the proof of adequacy is made easier by aligning these choices.
We define environments and closures as follows.
ClosEnv : Context β Set data Clos : Set where clos : β{Ξ} β (M : Ξ β’ β ) β ClosEnv Ξ β Clos ClosEnv Ξ = β (x : Ξ β β ) β Clos
As usual, we have the empty environment, and we can extend an environment.
β ' : ClosEnv β β ' () _,'_ : β {Ξ} β ClosEnv Ξ β Clos β ClosEnv (Ξ , β ) (Ξ³ ,' c) Z = c (Ξ³ ,' c) (S x) = Ξ³ x
Big-step evaluation
The big-step semantics is represented as a ternary relation, written Ξ³ β’ M β V, where Ξ³ is the environment, M is the input term, and V is the result value. A value is a closure whose term is a lambda abstraction.
data _β’_β_ : β{Ξ} β ClosEnv Ξ β (Ξ β’ β ) β Clos β Set where β-var : β{Ξ}{Ξ³ : ClosEnv Ξ}{x : Ξ β β }{Ξ}{Ξ΄ : ClosEnv Ξ}{M : Ξ β’ β }{V} β Ξ³ x β‘ clos M Ξ΄ β Ξ΄ β’ M β V ----------- β Ξ³ β’ ` x β V β-lam : β{Ξ}{Ξ³ : ClosEnv Ξ}{M : Ξ , β β’ β } β Ξ³ β’ Ζ M β clos (Ζ M) Ξ³ β-app : β{Ξ}{Ξ³ : ClosEnv Ξ}{L M : Ξ β’ β }{Ξ}{Ξ΄ : ClosEnv Ξ}{N : Ξ , β β’ β }{V} β Ξ³ β’ L β clos (Ζ N) Ξ΄ β (Ξ΄ ,' clos M Ξ³) β’ N β V --------------------------------------------------- β Ξ³ β’ L Β· M β V
The
β-varrule evaluates a variable by finding the associated closure in the environment and then evaluating the closure.The
β-lamrule turns a lambda abstraction into a closure by packaging it up with its environment.The
β-apprule performs function application by first evaluating the termLin operator position. If that produces a closure containing a lambda abstractionΖ N, then we evaluate the bodyNin an environment extended with the argumentM. Note thatMis not evaluated in ruleβ-appbecause this is call-by-name and not call-by-value.
Exercise big-step-eg (practice)
Show that (Ζ Ζ # 1) Β· ((Ζ # 0 Β· # 0) Β· (Ζ # 0 Β· # 0)) terminates under big-step call-by-name evaluation.
-- Your code goes here
The big-step semantics is deterministic
If the big-step relation evaluates a term M to both V and Vβ², then V and Vβ² must be identical. In other words, the call-by-name relation is a partial function. The proof is a straightforward induction on the two big-step derivations.
β-determ : β{Ξ}{Ξ³ : ClosEnv Ξ}{M : Ξ β’ β }{V V' : Clos} β Ξ³ β’ M β V β Ξ³ β’ M β V' β V β‘ V' β-determ (β-var eq1 mc) (β-var eq2 mc') with trans (sym eq1) eq2 ... | refl = β-determ mc mc' β-determ β-lam β-lam = refl β-determ (β-app mc mcβ) (β-app mc' mc'') with β-determ mc mc' ... | refl = β-determ mcβ mc''
Big-step evaluation implies beta reduction to a lambda
If big-step evaluation produces a value, then the input term can reduce to a lambda abstraction by beta reduction:
β
' β’ M β clos (Ζ Nβ²) Ξ΄
-----------------------------
β Ξ£[ N β β
, β
β’ β
] (M ββ Ζ N)The proof is by induction on the big-step derivation. As is often necessary, one must generalize the statement to get the induction to go through. In the case for β-app (function application), the argument is added to the environment, so the environment becomes non-empty. The corresponding Ξ² reduction substitutes the argument into the body of the lambda abstraction. So we generalize the lemma to allow an arbitrary environment Ξ³ and we add a premise that relates the environment Ξ³ to an equivalent substitution Ο.
The case for β-app also requires that we strengthen the conclusion. In the case for β-app we have Ξ³ β’ L β clos (Ξ» N) Ξ΄ and the induction hypothesis gives us L ββ Ζ Nβ², but we need to know that N and Nβ² are equivalent. In particular, that Nβ² β‘ subst Ο N where Ο is the substitution that is equivalent to Ξ΄. Therefore we expand the conclusion of the statement, stating that the results are equivalent.
We make the two notions of equivalence precise by defining the following two mutually-recursive predicates V β M and Ξ³ ββ Ο.
_β_ : Clos β (β β’ β ) β Set _ββ_ : β{Ξ} β ClosEnv Ξ β Subst Ξ β β Set (clos {Ξ} M Ξ³) β N = Ξ£[ Ο β Subst Ξ β ] Ξ³ ββ Ο Γ (N β‘ subst Ο M) Ξ³ ββ Ο = β x β (Ξ³ x) β (Ο x)
We can now state the main lemma:
If Ξ³ β’ M β V and Ξ³ ββ Ο,
then subst Ο M ββ N and V β N for some N.Before starting the proof, we establish a couple lemmas about equivalent environments and substitutions.
The empty environment is equivalent to the identity substitution ids, which we import from Chapter Substitution.
ββ-id : β ' ββ ids ββ-id ()
Of course, applying the identity substitution to a term returns the same term.
sub-id : β{Ξ} {A} {M : Ξ β’ A} β subst ids M β‘ M sub-id = plfa.part2.Substitution.sub-id
We define an auxiliary function for extending a substitution.
ext-subst : β{Ξ Ξ} β Subst Ξ Ξ β Ξ β’ β β Subst (Ξ , β ) Ξ ext-subst{Ξ}{Ξ} Ο N {A} = subst (subst-zero N) β exts Ο
The next lemma we need to prove states that if you start with an equivalent environment and substitution Ξ³ ββ Ο, extending them with an equivalent closure and term V β N produces an equivalent environment and substitution: (Ξ³ ,' V) ββ (ext-subst Ο N), or equivalently, (Ξ³ ,' V) x β (ext-subst Ο N) x for any variable x. The proof will be by induction on x and for the induction step we need the following lemma, which states that applying the composition of exts Ο and subst-zero to S x is the same as just Ο x, which is a corollary of a theorem in Chapter Substitution.
subst-zero-exts : β{Ξ Ξ}{Ο : Subst Ξ Ξ}{B}{M : Ξ β’ B}{x : Ξ β β } β (subst (subst-zero M) β exts Ο) (S x) β‘ Ο x subst-zero-exts {Ξ}{Ξ}{Ο}{B}{M}{x} = cong-app (plfa.part2.Substitution.subst-zero-exts-cons{Ο = Ο}) (S x)
So the proof of ββ-ext is as follows.
ββ-ext : β {Ξ} {Ξ³ : ClosEnv Ξ} {Ο : Subst Ξ β } {V} {N : β β’ β } β Ξ³ ββ Ο β V β N -------------------------- β (Ξ³ ,' V) ββ (ext-subst Ο N) ββ-ext {Ξ} {Ξ³} {Ο} {V} {N} Ξ³ββΟ VβN Z = VβN ββ-ext {Ξ} {Ξ³} {Ο} {V} {N} Ξ³ββΟ VβN (S x) rewrite subst-zero-exts {Ο = Ο}{M = N}{x} = Ξ³ββΟ x
We proceed by induction on the input variable.
If it is
Z, then we immediately conclude using the premiseV β N.If it is
S x, then we rewrite using thesubst-zero-extslemma and use the premiseΞ³ ββ Οto conclude.
To prove the main lemma, we need another technical lemma about substitution. Applying one substitution after another is the same as composing the two substitutions and then applying them.
sub-sub : β{Ξ Ξ Ξ£}{A}{M : Ξ β’ A} {Οβ : Subst Ξ Ξ}{Οβ : Subst Ξ Ξ£} β subst Οβ (subst Οβ M) β‘ subst (subst Οβ β Οβ) M sub-sub {M = M} = plfa.part2.Substitution.sub-sub {M = M}
We arrive at the main lemma: if M big steps to a closure V in environment Ξ³, and if Ξ³ ββ Ο, then subst Ο M reduces to some term N that is equivalent to V. We describe the proof below.
ββββ Γβ : β{Ξ}{Ξ³ : ClosEnv Ξ}{Ο : Subst Ξ β }{M : Ξ β’ β }{V : Clos} β Ξ³ β’ M β V β Ξ³ ββ Ο --------------------------------------- β Ξ£[ N β β β’ β ] (subst Ο M ββ N) Γ V β N ββββ Γβ {Ξ³ = Ξ³} (β-var{x = x} Ξ³xβ‘LΞ΄ Ξ΄β’LβV) Ξ³ββΟ with Ξ³ x | Ξ³ββΟ x | Ξ³xβ‘LΞ΄ ... | clos L Ξ΄ | β¨ Ο , β¨ Ξ΄ββΟ , Οxβ‘ΟL β© β© | refl with ββββ Γβ{Ο = Ο} Ξ΄β’LβV Ξ΄ββΟ ... | β¨ N , β¨ ΟLββ N , VβN β© β© rewrite Οxβ‘ΟL = β¨ N , β¨ ΟLββ N , VβN β© β© ββββ Γβ {Ο = Ο} {V = clos (Ζ N) Ξ³} (β-lam) Ξ³ββΟ = β¨ subst Ο (Ζ N) , β¨ subst Ο (Ζ N) β , β¨ Ο , β¨ Ξ³ββΟ , refl β© β© β© β© ββββ Γβ{Ξ}{Ξ³} {Ο = Ο} {L Β· M} {V} (β-app {N = N} LβΖNΞ΄ NβV) Ξ³ββΟ with ββββ Γβ{Ο = Ο} LβΖNΞ΄ Ξ³ββΟ ... | β¨ _ , β¨ ΟLββ ΖΟN , β¨ Ο , β¨ Ξ΄ββΟ , β‘ΖΟN β© β© β© β© rewrite β‘ΖΟN with ββββ Γβ {Ο = ext-subst Ο (subst Ο M)} NβV (Ξ» x β ββ-ext{Ο = Ο} Ξ΄ββΟ β¨ Ο , β¨ Ξ³ββΟ , refl β© β© x) | Ξ²{β }{subst (exts Ο) N}{subst Ο M} ... | β¨ N' , β¨ ββ N' , VβN' β© β© | ΖΟNΒ·ΟMββ rewrite sub-sub{M = N}{Οβ = exts Ο}{Οβ = subst-zero (subst Ο M)} = let rs = (Ζ subst (exts Ο) N) Β· subst Ο M βββ¨ ΖΟNΒ·ΟMββ β© ββ N' in let g = ββ -trans (appL-cong ΟLββ ΖΟN) rs in β¨ N' , β¨ g , VβN' β© β©
The proof is by induction on Ξ³ β’ M β V. We have three cases to consider.
Case
β-var. So we haveΞ³ x β‘ clos L Ξ΄andΞ΄ β’ L β V. We need to show thatsubst Ο (` x) ββ NandV β Nfor someN. The premiseΞ³ ββ Οtells us thatΞ³ x β Ο x, soclos L Ξ΄ β Ο x. By the definition ofβ, there exists aΟsuch thatΞ΄ ββ ΟandΟ x β‘ subst Ο L. UsingΞ΄ β’ L β VandΞ΄ ββ Ο, the induction hypothesis gives ussubst Ο L ββ NandV β Nfor someN. So we have shown thatsubst Ο x ββ NandV β Nfor someN.Case
β-lam. We immediately havesubst Ο (Ζ N) ββ subst Ο (Ζ N)andclos (subst Ο (Ζ N)) Ξ³ β subst Ο (Ζ N).Case
β-app. UsingΞ³ β’ L β clos (Ζ N) Ξ΄andΞ³ ββ Ο, the induction hypothesis gives ussubst Ο L ββ Ζ subst (exts Ο) N (1)and
Ξ΄ ββ Οfor someΟ. FromΞ³ββΟwe haveclos M Ξ³ β subst Ο M. Then with(Ξ΄ ,' clos M Ξ³) β’ N β V, the induction hypothesis gives usV β N'andsubst (subst (subst-zero (subst Ο M)) β (exts Ο)) N ββ N' (2)Meanwhile, by
Ξ², we have(Ζ subst (exts Ο) N) Β· subst Ο M ββ subst (subst-zero (subst Ο M)) (subst (exts Ο) N)which is the same as the following, by
sub-sub.(Ζ subst (exts Ο) N) Β· subst Ο M ββ subst (subst (subst-zero (subst Ο M)) β exts Ο) N (3)Using (3) and (2) we have
(Ζ subst (exts Ο) N) Β· subst Ο M ββ N' (4)From (1) we have
subst Ο L Β· subst Ο M ββ (Ζ subst (exts Ο) N) Β· subst Ο Mwhich we combine with (4) to conclude that
subst Ο L Β· subst Ο M ββ N'
With the main lemma complete, we establish the forward direction of the equivalence between the big-step semantics and beta reduction.
cbnβreduce : β{M : β β’ β }{Ξ}{Ξ΄ : ClosEnv Ξ}{Nβ² : Ξ , β β’ β } β β ' β’ M β clos (Ζ Nβ²) Ξ΄ ----------------------------- β Ξ£[ N β β , β β’ β ] (M ββ Ζ N) cbnβreduce {M}{Ξ}{Ξ΄}{Nβ²} Mβc with ββββ Γβ{Ο = ids} Mβc ββ-id ... | β¨ N , β¨ rs , β¨ Ο , β¨ h , eq2 β© β© β© β© rewrite sub-id{M = M} | eq2 = β¨ subst (exts Ο) Nβ² , rs β©
Exercise big-alt-implies-multi (practice)
Formulate an alternative big-step semantics, of the form M β N, for call-by-name that uses substitution instead of environments. That is, the analogue of the application rule β-app should perform substitution, as in N [ M ], instead of extending the environment with M. Prove that M β N implies M ββ N.
-- Your code goes here
Beta reduction to a lambda implies big-step evaluation
The proof of the backward direction, that beta reduction to a lambda implies that the call-by-name semantics produces a result, is more difficult to prove. The difficulty stems from reduction proceeding underneath lambda abstractions via the ΞΆ rule. The call-by-name semantics does not reduce under lambda, so a straightforward proof by induction on the reduction sequence is impossible. In the article Call-by-name, call-by-value, and the Ξ»-calculus, Plotkin proves the theorem in two steps, using two auxiliary reduction relations. The first step uses a classic technique called Curry-Feys standardisation. It relies on the notion of standard reduction sequence, which acts as a half-way point between full beta reduction and call-by-name by expanding call-by-name to also include reduction underneath lambda. Plotkin proves that M reduces to L if and only if M is related to L by a standard reduction sequence.
Theorem 1 (Standardisation)
`M ββ L` if and only if `M` goes to `L` via a standard reduction sequence.Plotkin then introduces left reduction, a small-step version of call-by-name and uses the above theorem to prove that beta reduction and left reduction are equivalent in the following sense.
Corollary 1
`M ββ Ζ N` if and only if `M` goes to `Ζ Nβ²`, for some `Nβ²`, by left reduction.The second step of the proof connects left reduction to call-by-name evaluation.
Theorem 2
`M` left reduces to `Ζ N` if and only if `β’ M β Ζ N`.(Plotkinβs call-by-name evaluator uses substitution instead of environments, which explains why the environment is omitted in β’ M β Ζ N in the above theorem statement.)
Putting Corollary 1 and Theorem 2 together, Plotkin proves that call-by-name evaluation is equivalent to beta reduction.
Corollary 2
`M ββ Ζ N` if and only if `β’ M β Ζ Nβ²` for some `Nβ²`.Plotkin also proves an analogous result for the Ξ»α΅₯ calculus, relating it to call-by-value evaluation. For a nice exposition of that proof, we recommend Chapter 5 of Semantics Engineering with PLT Redex by Felleisen, Findler, and Flatt.
Instead of proving the backwards direction via standardisation, as sketched above, we defer the proof until after we define a denotational semantics for the lambda calculus, at which point the proof of the backwards direction will fall out as a corollary to the soundness and adequacy of the denotational semantics.
Unicode
This chapter uses the following unicode:
β U+2248 ALMOST EQUAL TO (\~~ or \approx)
β U+2091 LATIN SUBSCRIPT SMALL LETTER E (\_e)
β’ U+22A2 RIGHT TACK (\|- or \vdash)
β U+21DB DOWNWARDS DOUBLE ARROW (\d= or \Downarrow)