Small step operational semantics specifies how programs execute 1 step at a time.
SSOS makes it easier to reason about complex features are we have a much more detailed picture of the execution.
Big Step Operational Semantics hides non-termination, SSOS does not.
Once again with the λ-Calculus our states are λ-terms and transitions are provided by inference rules. Our values are λ abstractions of the form λx.M) and are denoted as V.
(λx.M)V→vM[x\V]β
Essentially applies a β reduction.
Note the difference in arrow with ⟹ used for big step operational semantics and → used for SSOS
MN→vPNM→vPAPP1
VM→vVPM→vPAPP2
We use →v∗ as the reflexive and transitive closure of →v
As in Big step operational semantics, we can employ different evaluation strategies. Above, we have used call by value or eager evaluation. Below are the rules for call by name or lazy evaluation.
(λx.M)N→nM[x\N]β
MN→nPNM→nPAPP
Again, we define →n∗ as the reflexive and transitive closure of →n
M→n∗N⟺(M=N∪∃P.M→nP∩P→n∗N)
If M→v∗V and V is a value then M⟹vV
If M→n∗V and V is a value then M⟹nV
If M→vN and M→vP then N=P
If M→nN and M→nP then N=P
If M→vN then M=βN
If M→nN then M=βN
The untyped pure λ-Calculus Small step semantics has only:
- 2 context rules in the call-by-value version
- 1 context rule in the call-by-name version
However, other languages can, and do, have many more.
Evaluation context provides a way to compactly express context rules.
An evaluation context is a term with a special variable ∙ called a hole
If C is an evaluation context, then C[M] represents C with M substituted for ∙. For example:
((λx.x)∙)[M]=(λx.x)M
Every evaluation context C represents a context rule.
C[M]→vC[N]M→vN
expressing that M can be reduced to N in the context C where C is defined in the form:
C::=_∣_∣_∣…
Values (λ abtractions of the form λx.M) are denoted by V
C::=∙∣CM∣VC
C::=∙∣CM
Using these evaluation contexts, we can redefine the small-step semantics of the untyped pure λ-Calculus as:
(λx.M)V→vM[x\V]β
C[M]→vC[N]M→vNAPPC
(λx.M)N→nM[x\N]β
C[M]→nC[N]M→nNAPPC
Note: although these look the same, the definition of C for each is different. resulting in different rules
A normal form, with respect to a transition system, is a form that cannot be reduced further.
A term that has a normal form is said to converge otherwise they are said to diverge.
A normal form that is not a value is said to be stuck e.g. x or xx or x(λx.x) as values are defined as λx.M
If a term converges using call-by-value then it converges using call-by-name, although not necessarily to the same normal form.
- Reduces under λs
- Not used in practice
- As it can produce unwieldy expressions
If M is β-equal to a β-normal form N, then the normal order reduction reduces M to N
Call-by-name converges whenever normal order converges
Normal order reduction is defined as:
x⟹nox
λx.M⟹noλx.NM⟹noN
MN⟹noQM⟹nλx.PP[x\N]⟹noQ
MN⟹noQRM⟹nP=λx.TM⟹noQN⟹noR