Lectures onType Theory
Chapter 1
Chapter 1Core route

Judgments, Derivations, and Operational Semantics

Judgments, rules, and inductive definitions

Consider the expressions 0,suc(0),suc(suc(0)), A formal claim about one of these expressions is a judgment. A judgment form is a pattern for such claims: the one-place form  nat reads “is a numeral.” Filling its place with an expression a gives the judgment a nat.

0 nat
Nat-Z
a nat
suc(a) nat
Nat-S

A displayed rule has zero or more judgments as premises above the horizontal bar and one judgment as its conclusion below; the small-capital text at the right names it. Thus Nat-Z has no premises and establishes 0 nat. Rule Nat-S establishes suc(a) nat whenever its premise a nat has been established.

A derivation is a finite tree of rule instances: its root is the conclusion of the final rule, and the immediate subtrees derive that rule’s premises. For example,

0 nat
Nat-Z
suc(0) nat
Nat-S

has one leaf, the Nat-Z instance, and root suc(0) nat, the conclusion of the final Nat-S instance. The two displayed rules yield infinitely many numeral judgments. Which judgments have derivations? To prove a property of every numeral, may we inspect its derivation’s final rule, assume the property for each premise derivation, and prove it for the conclusion?

Definition 1.1 — Judgment forms and judgments

Fix a set O of syntactic objects, the formal expressions that may fill the argument places below. A judgment form of arity n1 is a relation symbol J with n argument places; a judgment, or instance of J, is a formal expression J(a1,,an) with a1,,anO, called its subjects. We restrict attention to judgment forms with at least one subject. A judgment is still only a formal expression. The rules determine which judgments hold.

For the first examples the syntactic objects are the finite ordered trees freely generated by operators of fixed arity. Examples are 0, suc(), and node(;). “Freely” means that different operators have disjoint images and that every operator is injective in its ordered arguments. Thus, for all syntactic objects a,b, 0suc(a), and suc(a)=suc(b) implies a=b. A dash marks an argument place. Semicolons separate arguments of one formal operator; they carry no logical meaning and play the role commas often play in programming notation. For example, every tree built from 0 and suc() remains a syntactic object when node(;) is also allowed.

Judgment notation may place the relation symbol before, between, or after its subjects. Thus a nat reads “a is a numeral” and aisb reads “a is the same numeral as b.”

Definition 1.2 — Rule

A rule over a collection of judgments is a pair of a finite list of judgments J1,,Jk (its premises, k0) and a single judgment J (its conclusion), displayed

J1Jk
J

A rule with no premises is an axiom; a rule set R is a set of rules over a common collection of judgments.

Remark 1.3 — Rule schemes

The symbol a in Nat-S is a metavariable, a placeholder that ranges over syntactic objects. The displayed rule is a rule scheme: it denotes one rule for every replacement of a by a syntactic object. Schemes may also have a side condition, a metalevel restriction such as a0. A side condition restricts the instances of the scheme; it is not one of the judgments being defined. When a proof follows such a finite tree upward, each judgmental premise has a premise subtree to which the proof can be applied recursively. A side condition has no subtree; it is checked only for the chosen rule instance.

Definition 1.4 — Inductive definition

Let R be a rule set. A rule-closed set for R is a set S of judgments such that for every rule of R with premises J1,,Jk and conclusion J: if J1,,JkS, then JS. The inductive definition generated by R is the least rule-closed set for R. We denote this set by I(R); its members are the judgments inductively defined by R.

The intersection of a family of sets contains exactly the objects that belong to every set in the family. Sets are ordered by inclusion, so a rule-closed set is least when it is contained in every other rule-closed set.

Proposition 1.5

For every rule set R the least R-closed set exists: it is the intersection of all R-closed sets of judgments.

Proof of Proposition 1.5

Proof. The set of all judgments is closed, so the family of closed sets is nonempty; and if the premises of a rule lie in an intersection of closed sets, its conclusion lies in each of them and hence in the intersection. The intersection of all closed sets is therefore closed, and it is contained in every closed set. ◻

Example 1.6 — Natural numbers

For each nonnegative integer k, define suc0(0)=0 and suck+1(0)=suc(suck(0)). For the rule set R consisting of the two rules displayed at the beginning of the section, put N={suck(0) natk is a nonnegative integer}. The set N is closed under Nat-Z and Nat-S, so minimality gives I(R)N. Conversely, Nat-Z followed by k uses of Nat-S derives suck(0) nat, so NI(R). Thus I(R)=N.

Exercise 1.1

★☆☆ Find a rule set and two sets of judgments, each closed under it, whose union is not closed. Thus intersection, rather than union, is the operation used in proposition 1.5.

Example 1.7 — Binary trees

The judgment form  tree is inductively defined by

emp tree
Tree-Emp
a1 treea2 tree
node(a1;a2) tree
Tree-Node

Example 1.8 — Equality of numerals

The two-place judgment form is is inductively defined by

0is0
Is-Z
aisb
suc(a)issuc(b)
Is-S

Remark 1.9 — Grammars are inductive definitions

A nonterminal is a placeholder naming the class of expressions being generated. A production is one permitted replacement for that placeholder. In n::=0suc(n), n is the nonterminal, and the two productions replace it by 0 or by suc(n). Starting from n, successive replacements can produce n,suc(n),suc(suc(n)),suc(suc(0)). The last expression has no placeholder left. It is generated by the grammar, and its replacement history has the same shape as its derivation built from Nat-Z and Nat-S.

The tree grammar t::=empnode(t;t) makes the defining restriction visible. After replacing t by node(t;t), either remaining t may be replaced by the same two productions; the expression in the other branch does not change the permitted choices. Formally, a context-free grammar consists of finite disjoint sets N and Σ, an element SN called its start symbol, and a finite set of productions A::=w,AN, where w is a finite word whose symbols belong to NΣ. The elements of N are the nonterminals. The elements of Σ are the terminal symbols that remain in a completed expression. The single nonterminal on the left is the context-free restriction: replacing A depends on A, not on adjacent symbols. A generated word is obtained by starting with S and replacing nonterminals until only terminal symbols remain. In the numeral grammar, N={n}, the start symbol is n, and the terminal tokens are 0, suc, the left parenthesis, and the right parenthesis. Its two productions have right sides 0 and suc(n); in the second right side, only n is a nonterminal. Thus the generated words are the printed forms of exactly those expressions a that have a derivation of a nat from the rules of example 1.6. Their parse trees, which record the successive production choices, become the freely generated syntax trees used above after one relabelling: label the choice n::=0 by a 0 leaf, and label n::=suc(n) by a suc node whose child records the remaining choice. The productions are compact notation for this inductive definition.

Inductive syntax also supports functions defined by recursive calls on smaller syntax trees. The next example isolates the data needed for such a definition. For a set X, the notation Xk means the set of ordered k-tuples of elements of X. The more general clause below also permits a recursive call on a smaller tree that is not an immediate child. For X={0,1,2,}, consider F(0)=0,F(suc(0))=1,F(suc(suc(a)))=F(a)+2. For a clause at an input tree r, let m(r) be its number of recursive calls, let bi(r) be the input tree of its i-th recursive call, and let gr combine the returned elements of X. At the third clause above, these data are m(suc(suc(a)))=1,b1(suc(suc(a)))=a,gsuc(suc(a))(n)=n+2. The three disjoint input forms select exactly one clause for every numeral.

Proposition 1.10 — Structural recursion on syntax

Let a syntactic class be the finite trees generated by a grammar. Fix a set X. For a syntax tree a, its constructor count |a| is the number of constructor occurrences in a. For every k-ary grammar constructor c, fix an operation fc:XkX. There is a unique function F on the syntactic class satisfying F(c(a1,,ak))=fc(F(a1),,F(ak)). More generally, suppose that for every syntax tree a one natural number m(a), trees b1(a),,bm(a)(a), and exactly one clause are specified, of the form F(a)=ga(F(b1(a)),,F(bm(a)(a))),ga:Xm(a)X, and that all recursive arguments satisfy |bi(a)|<|a|(1im(a)), Then the clauses determine a unique total function F. The requirements “exactly one” and ga:Xm(a)X are respectively the determinacy and totality conditions on the clauses. Decrease alone is insufficient: the two clauses F(0)=0 and F(0)=1 conflict, while omitting a clause for some tree leaves the function undefined there.

Thus fc combines the k recursively computed child results. For a binary constructor node(a1;a2), its clause has the programming form F(node(a1;a2))=fnode(F(a1),F(a2)).

Proof of Proposition 1.10 — Structural recursion on syntax

Proof. Here the height of a syntax tree is one for a nullary constructor and one plus the maximum height of its children otherwise. For each n0, define Fn on the trees of height at most n. The height-zero domain is empty. At stage n+1, the unique outer constructor of a tree determines its children, all of height at most n, so its displayed clause determines Fn+1. The construction leaves the values from earlier stages unchanged. Hence F(a):=Fn(a), for any n at least the height of a, is well defined and satisfies every clause. A second such function agrees at height zero and then at height n+1 by induction on n, which proves uniqueness. Height decreases for constructor children, but the general clause assumes only a decrease in constructor count. For that claim, use complete induction on constructor count: at count n, assume the claim for every count smaller than n. At a tree a, every F(bi(a)) in its unique clause has already been defined, and the total operation ga determines one element of X. A second function satisfying the clauses agrees on every bi by the induction hypothesis and therefore agrees at a. This proves existence, totality, and uniqueness. ◻

For the numeral grammar, take X={0,1,2,}, f0=1, and fsuc(n)=1+n. The resulting function is constructor count.

The numeral construction recurses on the immediate child of suc(a). In the general clause, a recursive argument bi(a) need only satisfy |bi(a)|<|a|; it need not be an immediate child of a.

A recursive construction with one total clause for each constructor and recursive calls only on constructor children therefore determines a unique total function by proposition 1.10.

Exercise 1.2

★☆☆ Combinator expressions are generated by the grammar a::=skap(a1;a2). Display the corresponding rules for a judgment a comb (remark 1.9), and give an inductive definition of a judgment len(a;n) relating each combinator a to the numeral n counting the occurrences of s and k in a. You may use the metalevel operation mn, defined recursively by 0n=n and suc(m)n=suc(mn), in the application rule. “Metalevel” means that is an ordinary mathematical operation used while specifying rule instances; it is neither a new judgment nor an additional premise above the bar.

Derivations

The closure definition says which judgments hold, but it does not yet record why a particular judgment holds. The record is a finite tree.

Definition 1.11 — Derivation

Let R be a rule set. Suppose a rule has premises J1,,Jk and conclusion J. Given derivations Di of all the premises, place those derivations above an instance of the rule. The resulting finite tree is a derivation of J. When k=0, the rule is an axiom and the tree has a single inference. A judgment J is derivable from R if some derivation D of J exists (written D::J and read “D is a derivation of J”). We draw these trees with the root—the conclusion—at the bottom and the premises growing upward. The height of a derivation is h(D):=1+max(h(D1),,h(Dk)), the maximum of the empty list being 0.

Example 1.12

The judgment suc(suc(0)) nat is derivable:

0 nat
Nat-Z
suc(0) nat
Nat-S
suc(suc(0)) nat
Nat-S

Exercise 1.3

★☆☆ Draw derivations, labeling every node with its rule, of suc(suc(0))issuc(suc(0))andnode(node(emp;emp);emp) tree.

Proposition 1.13

A judgment is derivable from R if and only if it belongs to I(R), the least set closed under R.

Proof of Proposition 1.13

Proof. Suppose first that D::J. We use complete (also called strong) induction on h(D). If the final rule has premises J1,,Jk, its immediate subtrees derive the Ji and have smaller height. Hence J1,,JkI(R) by the induction hypothesis. Closure under the final rule gives JI(R).

Conversely, let D be the set of derivable judgments. If J1,,JkD and R contains the rule J1,,Jk/J, place the chosen premise derivations above that rule instance. The resulting tree derives J; thus D is closed under R. Minimality gives I(R)D. ◻

Finiteness alone does not make derivations searchable: the labels and the rule-instance test must also be effective. An effective code for a set X is a natural-number representation equipped with a total algorithm decodeX:NX{invalid} such that every element of X is decoded from some natural number. Thus the decoder halts on every number and either returns one represented object or reports that the number is not a valid code. The property is semidecidable when an algorithm returns yes exactly on the positive instances, terminates with that answer on every positive instance, and may run forever on a negative instance. Such an algorithm has both a soundness obligation—every returned positive answer is correct—and a positive-termination obligation. By contrast, a property is decidable when an algorithm halts on every input and returns yes exactly on the positive instances.

Proposition 1.14 — Enumeration of derivations

Suppose that judgments and rule instances have effective codes and that equality of judgment codes is decidable. Then derivability is semidecidable.

Proof of Proposition 1.14 — Enumeration of derivations

Proof. First construct codes for finite rule-instance trees. Write node(T1,,Tk) for a tree whose root label has code and whose immediate subtrees are T1,,Tk, in that order. Define its code recursively by enc(node(T1,,Tk)):=11 ones011k ones0enc(T1)enc(Tk). A parser counts the ones before each of the first two zeroes, then recursively parses the recorded number of subtrees. It accepts a complete code only when no bits remain. For each length m, listing the 2m bit strings of length m therefore enumerates every finite rule-instance tree.

Given a judgment code for J, enumerate those bit strings. Skip a string if the parser fails or the total decoder returns invalid for a node label. If a label decodes to an instance with premises J1,,Jk and conclusion J0, require the node to have exactly k children and require their root conclusions to have the codes of J1,,Jk, in that order. Return yes only when the root conclusion has the same code as J.

Every parser and decoder call halts, so the check of each candidate tree halts. Every returned tree is a derivation of J, so the procedure is sound. If J is derivable, its finite derivation has one of the enumerated bit-string codes; the procedure reaches that code and returns yes. Hence it terminates on every derivable judgment. ◻

Thus the search terminates with a positive answer on every derivable judgment and may continue forever on an underivable one.

Exercise 1.4

★☆☆ Show that suc(0)is0 is not derivable from the rules of example 1.8, and that every derivation of suc(a)issuc(b) ends with an instance of Is-S; no induction is needed, only inspection of the final rule.

Rule induction

To prove that no malformed object has slipped into the least closed set, we reason according to the rule by which an object was built. This is rule induction: one proves one case for every rule that could conclude the judgment.

Theorem 1.15 — Rule induction

Let R be a rule set and let P be a property of judgments. Suppose that P is closed under R: for every rule instance with premises J1,,Jk and conclusion J, if P(J1),,P(Jk) all hold, then P(J) holds. Then P(J) holds for every judgment J derivable from R.

Proof of Theorem 1.15 — Rule induction

Proof. The set S={JP(J)} is closed under R by hypothesis, so I(R)S by minimality (definition 1.4), and every derivable judgment lies in I(R) by proposition 1.13. ◻

To “proceed by rule induction on D::J” is to apply theorem 1.15 with one case per rule, the assumptions P(Ji) being the induction hypotheses, the properties assumed for the premise derivations of that rule case. This principle concerns a property of the root judgment. A property that genuinely depends on the chosen finite derivation tree instead uses structural induction on that tree, equivalently complete induction on its height as in proposition 1.13. We call both arguments “induction on a derivation,” but state the strengthened property explicitly whenever the distinction matters. Specialized to example 1.6, rule induction is mathematical induction; to example 1.7, induction on binary trees. More generally, structural induction over a syntactic class is rule induction for the rules implicit in its grammar (remark 1.9); we use the two expressions interchangeably. Concretely, one proves one case for each grammar constructor and assumes the property for each immediate syntactic subexpression.

Proposition 1.16 — Strengthened rule induction

Let R be a rule set and P a property of judgments. In each rule case, suppose both that every premise Ji is derivable and that P(Ji) holds. If these assumptions imply P(J) for the conclusion, then P(J) holds for every derivable judgment J.

Proof of Proposition 1.16 — Strengthened rule induction

Proof. Apply theorem 1.15 to the conjunction Q(J):J is derivable and P(J). Thus Q(J) holds exactly when the two conjuncts in this definition hold. Suppose a rule has premises Ji, and assume Q(Ji) for each of them. From their first conjuncts, reapply the rule to derive its conclusion J. From the second conjuncts, use the assumed closure condition for P to obtain P(J). These are the two conjuncts of Q(J), so rule induction applies. ◻

Lemma 1.17 — Predecessor

If suc(a) nat is derivable, then so is a nat.

Proof of Lemma 1.17 — Predecessor

Proof. Use rule induction with the property: if the subject is suc(b), then b nat is derivable. The Nat-Z case is vacuous. In the Nat-S case, the required predecessor judgment is exactly the premise of the final rule. The strengthened rule-induction principle of proposition 1.16 makes that premise derivation available. This case does not use the induction hypothesis. ◻

Lemma 1.18 — Symmetry of numeral equality

If aisb is derivable, then so is bisa.

Proof of Lemma 1.18 — Symmetry of numeral equality

Proof. Apply rule induction to a derivation of aisb. For Is-Z, the required conclusion is again 0is0, obtained by Is-Z. For Is-S, the premise is aisb. The inductive hypothesis gives bisa, and Is-S gives suc(b)issuc(a). ◻

Exercise 1.5

★★☆ Prove by rule induction that a nat implies aisa. For transitivity, from derivations of aisb and bisc, derive aisc by induction on the first derivation and final-rule inspection on the second. Finally prove successor injectivity: from suc(a)issuc(b) derive aisb by inspecting the final rule.

Example 1.19 — Lists of numerals

Hold the numeral relation fixed, and define the list relation by

nil list
List-Nil
a nat list
cons(a;) list
List-Cons

The left premise of List-Cons is membership in the numeral relation; the right premise is recursive.

For example,

0 nat
Nat-Z
suc(0) nat
Nat-S
nil list
List-Nil
cons(suc(0);nil) list
List-Cons

Definition 1.20 — Iterated inductive definition

The list rules exhibit a one-way dependency: they may use the numeral relation as a premise while recursively defining the new list relation. In general, this is an iterated inductive definition: one inductive definition may use a previously completed one. Both old and recursively defined premises are judgmental premises. A side condition, by contrast, merely restricts which rule instances exist (remark 1.3).

Example 1.21 — Parity; simultaneity

The judgment forms  even and  odd are defined simultaneously by

0 even
Ev-Z
b odd
suc(b) even
Ev-S
a even
suc(a) odd
Od-S

Definition 1.22 — Simultaneous definition

The parity rules have a two-way dependency: an even derivation may contain an odd premise, and conversely. More generally, a simultaneous inductive definition uses one collection of rules to generate several judgment forms, and a rule may mention any of the forms in its premises. Their rule-induction principle treats all the forms together. Each premise—whether even or odd—provides the corresponding induction hypothesis.

Lemma 1.23 — Parity

If a nat is derivable, then a even or a odd is derivable.

Proof of Lemma 1.23 — Parity

Proof. Use rule induction with the property that a even or a odd is derivable. Case Nat-Z: 0 even by Ev-Z. Case Nat-S: if a is even, Od-S derives suc(a) as odd; if a is odd, Ev-S derives suc(a) as even. ◻

Lemma 1.24 — Parity expressions are numerals

If a even or a odd is derivable, then a nat is derivable.

Proof of Lemma 1.24 — Parity expressions are numerals

Proof. This is the first use of simultaneous rule induction. For both judgment forms use the property “the subject is a numeral.” There are three cases.

For Ev-Z, rule Nat-Z gives 0 nat. For Ev-S, the premise is b odd; its inductive hypothesis gives b nat, and Nat-S gives suc(b) nat. For Od-S, use the inductive hypothesis for the even premise and apply the same rule Nat-S. Thus the same induction proves the result for both the even and odd judgments. ◻

Lemma 1.25 — Disjointness of parity

No expression is derivable as both even and odd.

Proof of Lemma 1.25 — Disjointness of parity

Proof. We use simultaneous rule induction. The two properties are Pe(a):a odd is not derivable,Po(a):a even is not derivable. To prove that a judgment is not derivable, assume a derivation and inspect its final rule. A contradiction is obtained when that rule requires a premise excluded by the corresponding induction hypothesis. Here Pe(a) is proved for each derivation of a even, and Po(a) for each derivation of a odd. A rule case with premise b odd assumes Po(b), and a rule case with premise a even assumes Pe(a). These are the induction hypotheses. There are three rule cases.

For Ev-Z, no rule has conclusion 0 odd, so Pe(0) holds. For Ev-S, the premise is b odd and its inductive hypothesis says that b even is not derivable. If suc(b) odd were derivable, its final rule would have to be Od-S, whose premise is exactly b even, a contradiction. For Od-S, exchange the two judgment forms and exchange the rule names Ev-S and Od-S. Its premise is a even, so the induction hypothesis excludes a odd; final-rule inspection of a supposed derivation of suc(a) even then selects Ev-S and produces exactly that excluded premise. ◻

The inversion step inspects every rule that could have produced a given conclusion and reads off the premises forced by its outer form; it is the final-rule inspection used in the proof.

Exercise 1.6

★★☆ Prove by final-rule inspection that a derivation of suc(a) even contains a derivation of a odd, and a derivation of suc(a) odd contains a derivation of a even. Use these inversion facts to give a second proof of lemma 1.25. From either assumed parity derivation first obtain a nat by lemma 1.24; then induct on that numeral derivation and use the inversion facts in the successor case.

Example 1.26 — Functions by rules

Addition of numerals is the judgment sum(a;b;c), defined by

b nat
sum(0;b;b)
Sum-Z
sum(a;b;c)
sum(suc(a);b;suc(c))
Sum-S

The judgment sum(a;b;c) means that adding b to a produces c. The first argument controls the computation: Sum-Z returns b, and each use of Sum-S adds one successor to the result.

Lemma 1.27 — Subjects of addition are numerals

If sum(a;b;c) is derivable, then so are a nat, b nat, and c nat.

Proof of Lemma 1.27 — Subjects of addition are numerals

Proof. Induct on the sum derivation. A Sum-Z derivation has premise b nat and conclusion sum(0;b;b); Nat-Z derives the first subject, and the premise derives both the second and third. A Sum-S derivation has premise sum(a;b;c). Its induction hypothesis derives a nat, b nat, and c nat; Nat-S derives the first and third subjects of the conclusion, while b nat is unchanged. ◻

Proposition 1.28 — Addition is total

If a nat and b nat are derivable, then there is a c such that both c nat and sum(a;b;c) are derivable.

Proof of Proposition 1.28 — Addition is total

Proof. Use rule induction on the derivation of a nat, keeping the derivation of b nat fixed.

For Nat-Z, take c=b. The required sum is sum(0;b;b) by Sum-Z, and b nat is the fixed premise.

For Nat-S, the premise is a nat. By the induction hypothesis there is a c with c nat and sum(a;b;c). Rules Nat-S and Sum-S give respectively suc(c) nat and sum(suc(a);b;suc(c)). ◻

Lemma 1.29 — Addition is single-valued

If the two judgments sum(a;b;c)andsum(a;b;c) are derivable, then c=c as numeral syntax.

Proof of Lemma 1.29 — Addition is single-valued

Proof. Induct on the first sum derivation and inspect the last rule of the second. If the first derivation ends in Sum-Z, then a=0 and c=b. Only Sum-Z can conclude a sum judgment with first argument 0, so the second derivation also has c=b.

If the first derivation ends in Sum-S, write its premise as sum(a0;b;d); thus a=suc(a0) and c=suc(d). The second derivation must also end in Sum-S, with a premise sum(a0;b;d) and c=suc(d). The induction hypothesis gives d=d, hence c=c. ◻

By totality (proposition 1.28) and single-valuedness (lemma 1.29), each pair a,b of numerals has exactly one c satisfying sum(a;b;c). Thus the relation defined by the two rules is a function on numeral pairs.

Exercise 1.7

★☆☆ Exhibit a derivation of sum(suc(suc(0));suc(0);suc(suc(suc(0)))). Delete its final Sum-S. Which judgment remains at the root of the smaller derivation? Explain why this is the premise forced by inversion, not merely one possible way to construct the original tree.

Derivable and admissible rules

A primitive rule is one of the rules chosen to define a judgment. It may have premises; it is an axiom only when it has none. Suppose a proposed rule is not primitive. We may be able to derive its conclusion while treating its premises as assumptions. Or it may only be the case that whenever all its premises are derivable without assumptions, so is its conclusion. The first property is derivability of a rule; the second is admissibility.

Definition 1.30 — Hypothetical derivability

For a rule set R and a finite set Γ of judgments, hypothetical derivability is the relation ΓRJ that holds when J is derivable after adjoining, for every KΓ, the zero-premise rule

K

We abbreviate this enlarged rule set by RΓ; Γ= adds no hypothesis leaves. Read ΓRJ as “the rules R derive J when every judgment in Γ may be used as a hypothesis leaf.” Here Γ,J abbreviates the unordered finite set Γ{J}.

Proposition 1.31 — Structural properties

For any R, hypothetical derivability satisfies:

  1. (Reflexivity) Γ,JRJ;

  2. (Weakening) if ΓRJ, then Γ,KRJ;

  3. (Transitivity) if Γ,KRJ and ΓRK, then ΓRJ.

The hypothesis set becomes larger, but the requirement on a derivation becomes weaker: it may use any additional assumption, although it need not.

Proof of Proposition 1.31 — Structural properties

Proof. 1. The axiom J derives itself. 2. A derivation over RΓ is one over RΓ{K}. 3. Fix a derivation E of K from Γ, and induct on the given derivation D of J from Γ,K. If the final node is the hypothesis axiom K, replace it by E. If it is a different hypothesis axiom from Γ, retain it. If it is a primitive rule of R, transform each immediate subderivation by the inductive hypothesis and reapply that rule. The resulting tree derives J from Γ alone. ◻

Exercise 1.8

★★☆ Generalize transitivity to simultaneous discharge of finitely many hypotheses: if Γ,K1,,KnRJ and each ΓRKi, then ΓRJ. Give both a proof by repeated use of weakening and proposition 1.31.3 and a single induction that replaces all Ki-axiom nodes at once. For the latter, induct on the derivation of J with the property “after replacing every leaf labeled by some Ki with its fixed derivation from Γ, the transformed tree derives the same root from Γ.”

Definition 1.32 — Derivable and admissible rules

Let R be a rule set and r a candidate rule with premises J1,,Jk and conclusion J. The rule r is derivable with respect to R when J1,,JkRJ: a single derivation of J over R from the premises taken as axioms. It is an admissible rule with respect to R when, whenever each of J1,,Jk is derivable from R, so is J. A candidate rule scheme is derivable when every concrete instance is derivable, and admissible when every concrete instance is admissible.

Example 1.33

The rule

a nat
suc(suc(a)) nat
Nat-SS

is derivable with respect to the rules of example 1.6. Taking a nat as a hypothesis axiom gives the complete derivation

a nat
Hyp
suc(a) nat
Nat-S
suc(suc(a)) nat
Nat-S

Theorem 1.34

Every rule derivable with respect to R is admissible with respect to R; moreover, a rule derivable with respect to R is derivable with respect to any RR (stability under extension).

Proof of Theorem 1.34

Proof. Take the derivation of J from the premise axioms. Replace every occurrence of a premise axiom Ji by its given derivation without assumptions. Proposition 1.31.3 guarantees that the resulting tree derives J without assumptions. For k=2, the two transitive steps are J1,J2RJ,J2RJ1J2RJ,J2RJ,RJ2RJ. The middle derivation is the closed proof of J1 weakened by J2. For general k, eliminate J1,,Jk in that order; the i-th transitivity step uses the derivation already obtained from Ji,,Jk and the closed proof of Ji, weakened by the remaining hypotheses.

Stability: every non-hypothesis node of the given derivation is an instance of a rule of R and therefore of R; its hypothesis nodes are unchanged. The same tree is the required derivation over the larger rule set. ◻

Proposition 1.35 — Admissibility is conservative one-rule extension

A candidate rule r is admissible with respect to R if and only if, for every judgment J, R{r}JRJ.

Proof of Proposition 1.35 — Admissibility is conservative one-rule extension

Proof. Suppose first that r is admissible. The right-to-left implication reuses the same derivation because every rule of R belongs to the extension. For the converse, induct on an R{r}-derivation. If its final rule lies in R, transform every premise by the induction hypotheses and reapply that rule. If its final rule is an instance of r, the induction hypotheses give closed R-derivations of all its premises; by admissibility, its conclusion has a closed R-derivation.

Conversely, assume the displayed equivalence. Fix a concrete instance of r whose premises all have closed R-derivations. Reuse those derivations in the extension and apply the added rule once. Its conclusion is therefore derivable over R{r}. The right-to-left implication in the displayed equivalence gives a closed R-derivation of that conclusion. This is admissibility of the chosen instance; the instance was arbitrary. ◻

Exercise 1.9

★★☆ Reconstruct both directions of proposition 1.35 for a two-premise rule. In the forward direction, display the final-rule case for the added rule. In the reverse direction, display the one use of the added rule and the reflection step.

Example 1.35 — Admissibility is fragile

With respect to the parity rules of example 1.21, the inversion rule

suc(a) even
a odd
Ev-Inv

is admissible—any derivation of suc(a) even ends with Ev-S and so contains a derivation of a odd —but the scheme is not derivable. It suffices to inspect the instance a=0. From the sole hypothesis suc(0) even one cannot derive 0 odd: neither parity rule concludes 0 odd, so no possible final rule exists. Extend the rule set with the axiom suc(0) even: now Ev-Inv is inadmissible, since suc(0) even became derivable while 0 odd did not. Admissibility is as sensitive to the absent rules as to the present ones; this sensitivity is exactly what proofs by rule induction exploit.

Exercise 1.10

★★☆ Verify the admissibility argument instance by instance, including the fact that a derivation of suc(a) even can only end in Ev-S. Then draw the one-node derivation created by adjoining suc(0) even and explain why the same concrete instance a=0 destroys admissibility.

Arithmetic as a program

The judgment sum(a;b;c) computes a result only after its first two subjects have already been recognized as numerals. A program is less orderly: it may contain additions inside additions, and it must specify which unfinished part is evaluated first. We therefore turn the numerals into a small programming language before introducing functions.

Definition 1.36 — Arithmetic expressions and numerals

Arithmetic expressions are finite trees e::=0suc(e)add(e;e). The judgment e num is generated by

0 num
Num-Z
n num
suc(n) num
Num-S

A numeral is therefore an expression containing no add. A value is an expression designated as a completed result. In this first language the values are exactly the numerals.

The judgment n num has the same two rule schemes as the earlier judgment n nat.

Lemma 1.37 — The two numeral judgments coincide

For every expression n, n numn nat.

Proof of Lemma 1.37 — The two numeral judgments coincide

Proof. Rule induction in either direction re-applies the final rule with the other name. ◻

The two names mark different roles: nat is used by the addition relation, while num marks values of the arithmetic language. By lemma 1.37, either judgment may be converted to the other when needed.

Definition 1.38 — Small-step arithmetic evaluation

The judgment eAe, read “e takes one small step to e,” is generated by

eAe
suc(e)Asuc(e)
A-Suc
e1Ae1
add(e1;e2)Aadd(e1;e2)
A-Add-L
n1 nume2Ae2
add(n1;e2)Aadd(n1;e2)
A-Add-R
n2 num
add(0;n2)An2
A-Add-Z
n1 numn2 num
add(suc(n1);n2)Asuc(add(n1;n2))
A-Add-S

The first three rules are congruence rules: they allow a step inside a selected subexpression. This use of “congruence” means compatibility of evaluation with a term constructor. The first argument is evaluated before the second. The last two rules perform the addition only after both arguments are numerals.

For example, the first step of add(suc(add(0;suc(0)));0) is forced by two congruence rules. Read the innermost bar first: the inner addition contracts, that step is lifted through suc, and the result is then lifted through the outer addition.

0 num
Num-Z
suc(0) num
Num-S
add(0;suc(0))Asuc(0)
A-Add-Z
suc(add(0;suc(0)))Asuc(suc(0))
A-Suc
add(suc(add(0;suc(0)));0)Aadd(suc(suc(0));0)
A-Add-L

The remaining computation is add(suc(suc(0));0)AAAddSsuc(add(suc(0);0))AASuc/AAddSsuc(suc(add(0;0)))AASuc2/AAddZsuc(suc(0)).

Lemma 1.39 — Numerals do not step

If n num, there is no e with nAe.

Proof of Lemma 1.39 — Numerals do not step

Proof. Use rule induction on n num. No rule concludes a step whose source is 0. If the source is suc(n), the only possible final rule is A-Suc, and its premise would be a step from n, excluded by the induction hypothesis. ◻

Theorem 1.40 — Determinism

If eAe1 and eAe2, then e1=e2.

Proof of Theorem 1.40 — Determinism

Proof. Induct on the first step derivation. The strengthened induction property for a derivation D:eAe1 is P(D):for every derivation E:eAe2, one has e1=e2. Thus the induction hypothesis can be applied to any competing step from the same immediate subexpression, not merely to a previously chosen one.

For A-Suc, the second derivation can only end in A-Suc. If its argument reduct is e2, the induction hypothesis gives e1=e2. Applying the constructor suc() to both sides gives suc(e1)=suc(e2).

For A-Add-L, a competing A-Add-R, A-Add-Z, or A-Add-S derivation would contain a premise saying that the first argument is a numeral. That contradicts lemma 1.39, because the first derivation contains a step from it. Thus the second rule is again A-Add-L. The induction hypothesis gives equality of the two first-argument reducts, hence equality of the two add targets.

For A-Add-R, both sources have the form add(n1;e2) with n1 num. A competing A-Add-L would step from n1, contrary to lemma 1.39. A competing A-Add-Z or A-Add-S would require e2 num, contrary to the step premise of A-Add-R. Thus both derivations end in A-Add-R; the induction hypothesis equates their second-argument reducts, and congruence equates their targets.

For A-Add-Z, the outer form of the first argument excludes A-Add-S; the numeral premises and lemma 1.39 exclude both congruence rules. Only A-Add-Z remains, with the same target. For A-Add-S, the successor-headed first argument excludes A-Add-Z. Its two numeral premises and lemma 1.39 exclude both congruence rules. Both derivations therefore end in A-Add-S, whose target is the same expression suc(add(n1;n2)). Matching the common source against both A-Add-S conclusions and using injectivity of the free constructors forces the same n1 and n2 in the two rule instances. These cases exhaust the rules. ◻

Definition 1.41 — Many steps

The relation eAe, read “e takes zero or more steps to e,” is generated by

eAe
M-Refl
eAe1e1Ae2
eAe2
M-Step

The preceding three-step calculation is a derivation of add(suc(suc(0));0)Asuc(suc(0)).

Lemma 1.42 — Transitivity of many steps

If e0Ae1 and e1Ae2, then e0Ae2.

Proof of Lemma 1.42 — Transitivity of many steps

Proof. Induct on the first many-step derivation. For M-Refl, use the second derivation. For M-Step, retain its first one-step premise, compose its many-step tail with the second derivation by the induction hypothesis, and reapply M-Step. ◻

Definition 1.43 — Big-step arithmetic evaluation

The judgment eAn, read “e evaluates arithmetically to n,” is generated by

0A0
AB-Z
eAn
suc(e)Asuc(n)
AB-S
e1An1e2An2sum(n1;n2;n3)
add(e1;e2)An3
AB-Add

The last premise reuses the addition relation already proved total and single-valued in proposition 1.28, lemma 1.29.

Proof of Lemma 1.44 — Big-step results are numerals

Proof. Induct on the big-step derivation. The AB-Z and AB-S cases use Num-Z and Num-S. In the AB-Add case, lemma 1.27 gives n3 nat; induction on that derivation, replacing Nat-Z/Nat-S by Num-Z/Num-S, gives n3 num. ◻

Proof of Lemma 1.45 — Numerals evaluate to themselves

Proof. Use rule induction on n num. Rule Num-Z becomes AB-Z. In the Num-S case, reapply AB-S to the induction hypothesis. ◻

A complete evaluation tree for add(suc(0);suc(0)) is

0A0
AB-Z
suc(0)Asuc(0)
AB-S
0A0
AB-Z
suc(0)Asuc(0)
AB-S
0 nat
Nat-Z
suc(0) nat
Nat-S
sum(0;suc(0);suc(0))
Sum-Z
sum(suc(0);suc(0);suc(suc(0)))
Sum-S
add(suc(0);suc(0))Asuc(suc(0))
AB-Add

Lemma 1.46 — Congruence for many steps

If eAe, then suc(e)Asuc(e),add(e;d)Aadd(e;d). If also n num, then add(n;e)Aadd(n;e).

Proof of Lemma 1.46 — Congruence for many steps

Proof. Induct on the many-step derivation. The M-Refl case is M-Refl. In the M-Step case, use respectively A-Suc, A-Add-L, or A-Add-R on the first step, apply the induction hypothesis to the tail, and join them with M-Step. ◻

Lemma 1.47 — Numeral addition reduces

If sum(n1;n2;n3), then add(n1;n2)An3.

Proof of Lemma 1.47 — Numeral addition reduces

Proof. Use rule induction on the sum derivation. For Sum-Z, the rule premise is b nat, so lemma 1.37 gives b num, the premise of A-Add-Z. That rule gives the sole step, and M-Refl closes its target. For Sum-S, write the premise as sum(a;b;c). The induction hypothesis gives add(a;b)Ac, and the conclusion to prove is add(suc(a);b)Asuc(c). By lemma 1.27, lemma 1.37, a,b num. Hence add(suc(a);b)AAAddSsuc(add(a;b))AIH+lemma1.46suc(c). ◻

Theorem 1.48 — Big step implies small steps

If eAn, then eAn.

Proof of Theorem 1.48 — Big step implies small steps

Proof. Use rule induction on the big-step derivation. The AB-Z case is M-Refl. The AB-S case follows from the induction hypothesis and the first clause of lemma 1.46.

For AB-Add, lemma 1.44 applied to the first premise gives n1 num, as required by the second congruence. The induction hypotheses and the two addition congruences now give add(e1;e2)AIH1+lemma1.46add(n1;e2)AIH2+lemma1.46add(n1;n2)Alemma1.47n3. ◻

Proposition 1.49 — Arithmetic always advances or is a numeral

For every arithmetic expression e, either e num or there is an e with eAe.

Proof of Proposition 1.49 — Arithmetic always advances or is a numeral

Proof. Use structural induction on e. Zero is a numeral. For suc(e), the induction hypothesis either gives e num, whence Num-S applies, or a step lifted by A-Suc.

Let e=add(e1;e2). If e1 steps, use A-Add-L. Otherwise the induction hypothesis shows that e1 is a numeral. If e2 steps, use A-Add-R; otherwise the induction hypothesis shows that e2 is a numeral. Final-rule inspection of the first numeral derivation says that it is either 0 or suc(n); use A-Add-Z or A-Add-S, respectively. ◻

Exercise 1.11

★★☆ Draw every one-step derivation in the evaluation of add(add(0;suc(0));suc(0))Asuc(suc(0)). Then derive add(add(0;suc(0));suc(0))Asuc(suc(0)).

Bound variables and substitution

Function terms introduce variables and binders. The first task is to state the raw trees on which binding operations act.

Definition 1.50 — Raw untyped terms

Fix a countably infinite supply of variables. Raw terms are the formal trees generated by e::=xλx.eeettffif(e;e;e)0suc(e)add(e;e). Variables, abstractions, and applications form the untyped lambda calculus (ULC). Here untyped means that no type judgment restricts which generated trees count as terms: for example, ttff is a raw term even though a Boolean occurs in function position. We extend the ULC grammar with Boolean and arithmetic terms. Application is written by juxtaposition: e1e2 means “apply e1 to e2,” and it associates to the left. The abstraction λx.e is read “the anonymous function sending x to e”; it binds x in its body. For application, FV(e1e2)=FV(e1)FV(e2); the other nonbinding constructors recurse in each argument. The binding clauses are FV(x)={x},FV(λx.b)=FV(b){x}. The constants tt and ff are the two Boolean values, and if(e;e1;e2) selects a branch according to its first argument. Call a term a closed term when its free-variable set is empty. This use of “closed” is distinct from a set of judgments being closed under a rule set. Write Names(e) for all free and bound names in e. Write BN(e) for its binder labels, defined by BN(x)=, BN(λx.b)={x}BN(b), and union over the arguments of every nonbinding constructor. Finally, |e| is its number of constructor nodes.

Evaluation must replace a free variable in a function body by an argument. Literal replacement is unsafe: it may turn a free variable in the argument into a bound one. The failure occurs already in one abstraction. Define the raw operation [a/x]naive to replace each free x by a while recursing under every differently named binder. Its abstraction clause gives (λy.x)[y/x]naive=λy.x[y/x]naive=λy.y. The formerly free inserted y has become bound. Capture-avoiding substitution must therefore rename a conflicting binder before inserting the argument.

The following binding-edge diagram records the same failure. Solid edges are syntax-tree edges. A dashed edge runs from a binder to the occurrences it binds, and the boxed node is the free occurrence inserted for x. Literal replacement moves that node below the binder and thereby creates the dashed edge.

Mathematical diagramDiagram

The represented equation is (λy.x)[y/x]naive=λy.y; the dashed edge is absent before substitution and present afterward.

Definition 1.51 — Fresh renaming

If zNames(e), the fresh renaming ez/x replaces the free occurrences of x by z. Read z/x as “rename x to fresh z.” Square brackets [a/x] instead mean insertion of the possibly compound term a for x. The variable and abstraction clauses are xz/x=z,yz/x=y(yx),(λx.b)z/x=λx.b,(λy.b)z/x=λy.bz/x(yx). Every other constructor recursively renames each argument.

Lemma 1.52 — Fresh-renaming equations

Let e be a raw term and let x,z be variables with zNames(e). Then items 1–3 hold for this e,x,z. Items 4 and 5 hold under the additional hypotheses printed in those items; these hypotheses include every freshness premise required by definition 1.51.

  1. Size. |ez/x|=|e|.

  2. Free variables. FV(ez/x)=(FV(e){x})({z} if xFV(e), else ).

  3. Absent source. If xFV(e), then the renaming fixes the term: ez/x=e.

  4. Composition. Suppose x,y,z are distinct and yNames(e),zNames(ey/x). Then ey/xz/y=ez/x.

  5. Commutation. If x,y,z,w are pairwise distinct and z,w are fresh for e, then the two independent renamings commute: ez/xw/y=ew/yz/x.

Proof of Lemma 1.52 — Fresh-renaming equations

Proof. For items 1–3, prove simultaneously, by structural induction on e, the three claims for every source x and every target z outside Names(e). A variable has the two subcases e=x and ex. Constants are fixed. For application, conditional, successor, and addition, apply the corresponding induction hypotheses to each immediate argument and then use, respectively, addition of constructor counts and union of free-variable sets.

Let e=λu.b. If u=x, fresh renaming stops: size is unchanged, the free-variable formula deletes x=u on both sides, and the absent-source premise xFV(λx.b) makes item 3 the defining identity. If ux, then zNames(λu.b) gives zu and zNames(b). The renaming passes under u. The three induction hypotheses for b give the body size, free-variable, and absent-source equations; reattaching u preserves size, and deleting u from both free-variable sets gives the required abstraction equations.

For items 4 and 5, use separate structural inductions on e. Variables, constants, and nonbinding constructors follow from the defining clauses and the induction hypotheses on their immediate arguments.

Here is the composition calculation, including its binder side conditions. If u=x, the first renaming stops and the second changes nothing because yNames(λx.b); the right-hand renaming also stops. The case u=y is excluded by that same freshness condition. Otherwise both renamings pass under u, and the induction hypothesis on b gives λu.by/xz/y=λu.bz/x. The case u=z is excluded by freshness of the second target. For commutation, the binder is either one of the two source names, in which case that renaming stops and the other passes under the binder, or neither source, in which case both pass under it and the induction hypothesis on b applies. Pairwise distinctness and freshness of z,w exclude the two target-name cases. These cases exhaust the abstraction clauses. ◻

Exercise 1.12

★☆☆ Let x,y,z,w be pairwise distinct, with w absent from the displayed terms. Compute (λy.x(yz))w/xand(λx.xy)w/x. For each result, verify the free-variable equation in lemma 1.52 and identify the abstraction clause used.

The tempting two-name clause λx.b=α?λy.cc=by/x is not capture-safe: it would identify λx.y with λy.y. Renaming both binders to a third name fresh for both raw terms avoids that failure.

Definition 1.53 — Alpha-equivalence

Alpha-equivalence e=αe identifies raw terms that differ only in bound-variable names; it is defined by complete induction on |e|+|e|. Variables satisfy x=αy exactly when x=y. Two nonbinding operator applications are alpha-equivalent when they have the same operator and their corresponding arguments are alpha-equivalent. Two abstractions satisfy λx.b=αλy.c when there is a variable z, occurring nowhere in either raw term, such that bz/x=αcz/y. Expressions with different outer constructors are not alpha-equivalent. The common fresh opening makes the two bodies directly comparable while ignoring the spelling of their binders. The recursion is well founded: every compared argument is smaller than its parent, and |bz/x|=|b| by the size clause of lemma 1.52.

The common-opening clause compares two abstractions by sending both binder labels to one fresh name. In the diagram, solid arrows are fresh-renaming operations, and the horizontal double line is the smaller alpha-equivalence comparison that defines the comparison above it.

Mathematical diagramDiagram

The diagram represents the defining equation λx.b=αλy.cz(Names(λx.b)Names(λy.c)).bz/x=αcz/y. Its induction measure decreases because |b|+|c|<|λx.b|+|λy.c|. The diagram records this bookkeeping; it does not replace the compatibility proof below.

Thus λx.λy.x=αλu.λv.u,λx.λy.x=αλu.λv.v. Renaming the outer binders of the first pair to a name w fresh for all four binders gives λy.w and λv.w. These terms are alpha-equivalent after opening their inner binders once more.

Lemma 1.54 — Alpha compatibility and common openings

Suppose e=αe.

  1. The two terms have the same constructor count, outer constructor, and set of free variables.

  2. If z is fresh for both terms, then ez/x=αez/x.

  3. If e=λx.b, e=λy.c, and z is fresh for both raw terms, then bz/x=αcz/y.

Proof of Lemma 1.54 — Alpha compatibility and common openings

Proof. For item 1, induct over the defining comparison. For every nonbinding constructor, apply the induction hypothesis to each argument. In the abstraction case, the two opened bodies have the same constructor count by the induction hypothesis and the size clause of lemma 1.52, so the original bodies do also. For free variables, apply the free-variable clause of lemma 1.52 to the common fresh opening and delete the opening name on both sides. The outer constructor is fixed by every defining clause.

For items 2 and 3, the obstruction is a mutual dependency: changing the fresh name in a common opening uses compatibility of renaming, while compatibility under an abstraction uses independence of the common opening. Define two quantified claims. The claim C0(N) is item 3 for every alpha-equivalent pair of abstractions whose constructor counts sum to N, for every common opening name fresh for the two complete abstractions. The claim C1(N) is item 2 for every alpha-equivalent pair whose constructor counts sum to N, for every source name x and every target z fresh for the two complete terms. Prove all Cq(N) by complete induction on (N,q)N×{0,1}, ordered lexicographically. For N<N, the relevant comparisons are (N,0)<(N,0)because the first coordinate decreases,(N,1)<(N,0)because the first coordinate decreases,(N,0)<(N,1)because 0<1 at fixed N. This order is well founded. Indeed, if a descending sequence lowered the first coordinate infinitely often, it would give an infinite strictly decreasing sequence of natural numbers. Otherwise there is an index after which that coordinate is constant; beyond that index, the second coordinate can decrease from 1 to 0 only once. At the case (N,q), the induction hypothesis contains every Cq(N) with (N,q)<(N,q). The proof of C0(N) invokes C1(N) only for opened bodies with N<N. The abstraction case of C1(N) first invokes C0(N), then invokes C1(N) for smaller bodies. Thus the induction order records the dependency chain C1(N) (N<N)C0(N)C1(N). These are the only cross-invocations.

Common opening: C0(N). For item 3, the definition gives a fresh witness w with bw/x=αcw/y. If w=z, this is already the required conclusion. Otherwise apply the renaming-compatibility induction hypothesis to the smaller bodies with z/w. The names x,w,z are then distinct, and z is fresh for both opened bodies, because it occurs in neither original raw term and differs from w. The composition clause of lemma 1.52 changes the two resulting terms to bz/x and cz/y. Thus the common opening is independent of the witness used in the definition.

Renaming compatibility: C1(N). For item 2, variables are direct, and each nonbinding constructor follows by applying the induction hypothesis to its arguments. Suppose the compared terms are λu.b and λv.c. Choose r fresh for both bodies and their binders, and distinct from x,z. If x=z, freshness says that x is absent from both complete terms. Hence the absent-source equation gives ez/x=eandez/x=e, so the desired alpha-equivalence is the hypothesis. Assume henceforth that xz. The common-opening claim gives br/u=αcr/v. Apply the renaming-compatibility induction hypothesis to these smaller bodies with z/x. The following table names the equation used on each side in the four binder cases: u=xv=xboth abstraction renamings stopu=xvxabsent source on the left; commutation on the rightuxv=xcommutation on the left; absent source on the rightuxvxcommutation on both sides. If neither u nor v equals x, the commutation clause of lemma 1.52 commutes the opening and the free renaming: br/uz/x=bz/xr/u. The same equation holds for c with u,b replaced by v,c, so the abstraction clause with witness r proves this case.

If u=v=x, both abstraction renamings stop, so the original alpha-equivalence is the conclusion. In the mixed case u=x and vx, the left abstraction renaming stops. On opened bodies, xFV(br/x) by the free-variable clause of lemma 1.52; hence its later z/x is the identity, while commutation gives cr/vz/x=cz/xr/v. Thus r witnesses alpha-equivalence of the renamed abstractions. The other mixed case ux and v=x uses the same two equations on the opposite bodies: commutation on b and the absent-source equation on cr/x. These four binder cases exhaust item 2. ◻

Exercise 1.13

★☆☆ Let e=λx.λy.x and e=λu.λv.u. Choose w outside Names(e)Names(e), compute the two outer openings, then choose rNames(λy.w)Names(λv.w) and compute the inner openings. Use the variable and abstraction clauses of definition 1.53 to derive e=αe. Explain why choosing w=y would not meet the common opening hypothesis.

Proposition 1.55 — Alpha-equivalence is an equivalence relation

For all raw terms e,e,e, alpha-equivalence is reflexive (e=αe), symmetric (e=αee=αe), and transitive (e=αee=αee=αe). These three properties make it an equivalence relation. It preserves constructor count, outer constructor, and free variables. It is a congruence: replacing any immediate argument of a term constructor by an alpha-equivalent term preserves alpha-equivalence of the whole term.

Proof of Proposition 1.55 — Alpha-equivalence is an equivalence relation

Proof. Reflexivity is induction on syntax; symmetry is induction on the given alpha-equivalence comparison. For reflexivity of an abstraction λx.b, choose zNames(λx.b) and open both copies with z. The induction hypothesis gives b=αb, and lemma 1.54(2) transports it to bz/x=αbz/x, as required by the abstraction clause. Symmetry uses the same witness in the opposite order.

For transitivity, use complete induction on the common constructor count, which exists by lemma 1.54(1). In the abstraction case suppose λx.b=αλy.c and λy.c=αλu.d. Choose one name w fresh for all three raw terms. Lemma 1.54(3) gives bw/x=αcw/y,cw/y=αdw/u. The complete-induction hypothesis applies to these smaller bodies; their transitivity and the abstraction clause yield λx.b=αλu.d. For a nonbinding constructor, apply the induction hypothesis to every argument. Every defining clause preserves the outer constructor. Those same clauses prove congruence for nonbinding constructors; the common-opening abstraction clause and lemma 1.54(2) prove it for abstraction. ◻

The avoid set must grow between siblings. For example, clean the left child of (λx.x)(λy.y) against a finite set X, obtaining λp.p with pX. Clean the right child against X{p}, obtaining λq.q. Then qX{p}, so the rebuilt application has two distinct binder labels, both outside X. Cleaning both children independently against X would not force pq.

Lemma 1.56 — Fresh representatives and common opening

Let X be finite.

  1. For every raw term e, there is a raw term eX with e=αeX, with BN(eX)X=, and with distinct labels at all abstraction nodes.

  2. If λx.b=αλy.c and z occurs nowhere in either representative, then bz/x=αcz/y.

Proof of Lemma 1.56 — Fresh representatives and common opening

Proof. Strengthen the first clause before applying complete induction on |e|: for every finite avoid set X, construct eX with all three stated properties. The induction hypothesis is available for every smaller raw term and every finite avoid set.

For a nonbinding constructor with immediate subterms e1,,ek, process the children from left to right. Set X0=X. After constructing (ei)Xi1, set Xi=Xi1BN((ei)Xi1). The induction hypothesis says that the i-th child’s binder labels avoid Xi1. Hence they avoid X and every earlier child’s binder labels. Rebuilding the constructor preserves alpha-equivalence by congruence and makes all sibling binder-label sets pairwise disjoint.

For an abstraction e=λx.b, choose zXNames(b){x} and set bz=bz/x. Since |bz|=|b|<|λx.b|, apply the strengthened induction hypothesis to bz with avoid set X{z}. It gives a raw term c with bz=αc, distinct binder labels, and BN(c)(X{z})=. Choose rNames(b)Names(bz/x)Names(c){x,z}. Compatibility of bz=αc with r/z and fresh-renaming composition give br/x=αcr/z. The abstraction clause therefore relates λx.b to λz.c. The outer label z avoids X, the inner labels avoid X{z}, and the induction hypothesis already makes the inner labels pairwise distinct. Thus all labels in λz.c are distinct and avoid X, completing the strengthened induction.

The second clause is exactly lemma 1.54(3). ◻

Convention 1.57 — Bound names

The alpha-equivalence class of a raw term e, written [e], is the set of all raw terms alpha-equivalent to e. A quotient term is one such class. Henceforth terms are quotient terms, and each written raw expression denotes one representative of its class. By lemma 1.56, before a calculation we may choose a representative whose bound names avoid any specified finite collection of names. In particular, given raw terms a1,,ak and variables x1,,xm, we may require all binders to avoid the finite set Names(a1)Names(ak){x1,,xm}. Ordinary equality = compares these quotient terms; r=αs continues to compare the explicitly named raw representatives r and s.

Definition 1.59 — Fresh renaming of quotient terms

Let E be a quotient term, let x,z be variables, and suppose zFV(E). Here FV(E) is the common free-variable set of the representatives of E, whose equality follows from lemma 1.54(1). Choose a raw representative rE with zNames(r), and define Ez/x:=[rz/x]. Such a representative exists: lemma 1.56 moves all bound names away from z, while lemma 1.54(1) gives FV(r)=FV(E). If r,sE are two representatives with z fresh for both, then lemma 1.54(2) gives rz/x=αsz/x. Hence the displayed alpha-class is independent of the representative.

Definition 1.58 — Capture-avoiding substitution

Capture-avoiding substitution inserts a term without turning its free variables into bound occurrences. By lemma 1.56, choose a representative of e whose bound names are pairwise distinct and avoid FV(a){x}. On this representative define e[a/x] structurally: x[a/x]=a,y[a/x]=y(yx),(λy.b)[a/x]=λy.b[a/x],(e1e2)[a/x]=e1[a/x]e2[a/x]. The abstraction equation assumes yx; the chosen representative also has yFV(a). There is no separate shadowing equation on the chosen representative: a source binder named x has already been alpha-renamed away from x, and the abstraction equation returns an alpha-equivalent copy of that binder and body. For a conditional, successor, or addition, substitute recursively in each immediate subterm. Substitution fixes the three constants tt, ff, and 0. The resulting alpha-equivalence class is e[a/x].

This representative choice repairs the failed literal calculation at the start of the section. Capture avoidance first chooses z{x,y}: (λy.x)[y/x]=(λz.x)[y/x]=λz.y. The first equality is equality of alpha-classes; on the two displayed raw representatives, the corresponding structural substitution outputs are alpha-equivalent.

The substitution-composition equation below says that performing the x-substitution before the y-substitution requires updating the inserted term a by that later substitution. For distinct x,y,z, (xy)[z/x][tt/y]=ztt=(xy)[tt/y][z[tt/y]/x]. The condition xy keeps the two replacement sites distinct, and xFV(c) prevents the right-hand x-substitution from rewriting inside the term c inserted by the first step.

The abstraction case of representative independence needs one interchange equation. It is proved on raw representatives before substitution is passed to alpha-equivalence classes.

Lemma 1.59 — Fresh opening commutes with substitution

Let b and a be raw representatives, and let x,u,z be pairwise distinct. Suppose every binder of b avoids {x,u}FV(a), suppose uFV(a), and suppose zNames(b)Names(a). Then bz/u[a/x]=αb[a/x]z/u.

Proof of Lemma 1.59 — Fresh opening commutes with substitution

Proof. Use structural induction on b. For the variable u, both sides are z. For the variable x, the left side is a; the right side is az/u=a by the absent-source equation and uFV(a). Every other variable and every constant is fixed. Each nonbinding constructor follows by applying the induction hypothesis to its immediate subterms.

For an abstraction λr.c, the representative choice gives r{x,u,z}FV(a). Opening and substitution therefore both pass under r. The induction hypothesis gives cz/u[a/x]=αc[a/x]z/u, and abstraction congruence reattaches λr. ◻

Proposition 1.60 — Substitution is well defined

The alpha-class in definition 1.58 is independent of the chosen representative of e whose binders are pairwise distinct and avoid FV(a){x}, and of the representative of a. Moreover:

  1. if xFV(e), then e[a/x]=e;

  2. if xFV(e), then FV(e[a/x])=(FV(e){x})FV(a);

  3. if r is a raw representative of e and zNames(r), then substitution by z agrees with fresh renaming of that representative: e[z/x]=[rz/x];

  4. if xy and xFV(c), then e[a/x][c/y]=e[c/y][a[c/y]/x].

Proof of Proposition 1.60 — Substitution is well defined

Proof. Independence of the source representative. For independence of the representative of e, use complete induction on the common constructor count of alpha-equivalent representatives; its equality follows from proposition 1.55. Hold the representative of a fixed. Variables and constants are direct, and nonbinding constructors use congruence after the induction hypotheses. For abstractions λu.b=αλv.c, choose the clean representatives with pairwise distinct bound names. Their outer binders satisfy u,vFV(a){x}, and no binder inside b equals u, while no binder inside c equals v. Choose zNames(λu.b)Names(λv.c)Names(a){x}. The common-opening lemma gives bz/u=αcz/v. The induction hypothesis on these smaller bodies gives bz/u[a/x]=αcz/v[a/x]. Apply lemma 1.59 on both sides to obtain b[a/x]z/u=αc[a/x]z/v. The displayed choice makes z fresh for both substituted abstractions, so this equation is exactly the abstraction clause proving λu.b[a/x]=αλv.c[a/x].

Independence of the inserted representative. Let a=αa and choose one representative of e whose binders avoid FV(a){x}; alpha-equivalence gives FV(a)=FV(a). Structural induction on this representative proves e[a/x]=αe[a/x]. The variable x case is the hypothesis a=αa; other variables and constants are fixed; nonbinding constructors use congruence; and a clean abstraction reattaches its binder after the induction hypothesis for its body.

The absent-source and free-variable laws. Claims 1 and 2 are structural inductions on a representative whose bound names avoid the finite sets named in definition 1.58. For the free-variable equation, the variable case uses xFV(e), and every nonbinding constructor follows by taking unions. In each abstraction case the binder has already been chosen away from the names under discussion, so the induction hypothesis applies to the body; deleting the same binder on both sides gives the free-variable equation, and reattaching it gives the absent-source equation.

Substitution by a fresh variable. For claim 3, begin with the arbitrary representative r named in the statement. Choose r0=αr whose binders avoid {x,z}. Since zNames(r), lemma 1.54(1) gives FV(r0)=FV(r), so zFV(r0). The binder choice therefore gives zNames(r0). Alpha compatibility yields [rz/x]=[r0z/x]. Structural induction on r0 now proves [r0][z/x]=[r0z/x]. The variable x is the defining fresh-renaming equation. Other variables and constants are fixed, and nonbinding constructors use the induction hypotheses. At λu.b, the choice of r0 gives ux,z, so substitution and fresh renaming both pass under u; reattaching u proves the abstraction case. Source-representative independence then replaces [r0] by e=[r], proving claim 3 even when r itself has a binder named x.

Substitution composition. For the substitution-composition equation, strengthen the induction statement by choosing every binder in e outside {x,y}FV(a)FV(c). Variables give the two sides directly; the case e=y uses xFV(c). Apply the induction hypothesis to every argument of a nonbinding constructor. For e=λz.b, the choice of z makes every abstraction equation applicable on both sides. The induction hypothesis gives b[a/x][c/y]=αb[c/y][a[c/y]/x], and abstraction congruence completes the binder-sensitive case. ◻

Lemma 1.63 — Fresh-opening cancellation

Let b and v be raw representatives, put B=[b] and V=[v], let x and z be distinct variables, and suppose zNames(b). Then [bz/x][V/z]=B[V/x] in the quotient of raw terms by alpha-equivalence.

Proof of Lemma 1.63 — Fresh-opening cancellation

Proof. Choose b0=αb whose binders avoid {x,z}FV(v). Because zNames(b), the name z occurs neither free nor bound in b0. Alpha compatibility gives bz/x=αb0z/x, while [b]=[b0]. Well-definedness of substitution gives [bz/x][V/z]=[b0z/x][V/z],[b][V/x]=[b0][V/x].

It remains to prove the equation for b0; use structural induction on b0. At the variable x, both sides are V. For any other variable u, the case assumption gives ux, and freshness gives uz, so both sides are [u]. Both substitutions fix every constant. For a nonbinding constructor, apply the induction hypothesis to every immediate subterm and reattach the constructor.

For b0=λu.c, the representative choice gives u{x,z}FV(v). Fresh renaming and both substitutions pass under u. The induction hypothesis equates the quotient classes of the two bodies, and abstraction congruence reattaches λu.. The two displayed well-definedness equalities then replace b0 by b, which proves the stated equation. ◻

Exercise 1.14

★★☆ Let x,y,z be distinct. Compute (λy.x(yz))[(yx)/x] from a representative with fresh bound names, and list the free variables of the result. Then verify equation 1.1 on e=λz.xy with a=y and c=tt.

Functions and evaluation order

The extended syntax contains two kinds of value: data already computed and an abstraction waiting for an argument. Evaluation is call by value. Thus an application first evaluates its function, then its argument, and only then performs substitution. The collection of rules specifying how terms execute is their operational semantics, also called their dynamics.

Definition 1.64 — Raw values and raw numeric values

For raw representatives, the predicates RawVal(v) and RawNum(n) are generated by

RawVal(λx.b)
V-Lam
RawVal(tt)
V-True
RawVal(ff)
V-False
RawNum(n)
RawVal(n)
V-Num
RawNum(0)
Num-Z
RawNum(n)
RawNum(suc(n))
Num-S

The last two rules define exactly the numeral expressions introduced in definition 1.36; the separate judgment records when an arithmetic value is numeric. The separate numeric judgment prevents suc(λx.x) and add(0;λx.x) from being mistaken for values.

Definition 1.65 — Raw call-by-value rule instances

The one-step judgment ee, read “takes one step,” combines call-by-value function and boolean reduction with the arithmetic rules. It is generated on raw representatives by the following rules. For this definition only, ee is read between raw representatives. In E-Beta, the term displayed as b[v/x] ranges over the raw representatives of the alpha-class produced by definition 1.58. That substitution cleans binders internally; the displayed source binder has no additional freshness side condition.

e1e1
e1e2e1e2
E-App-L
RawVal(v1)e2e2
v1e2v1e2
E-App-R
RawVal(v)
(λx.b)vb[v/x]
E-Beta
ee
if(e;e1;e2)if(e;e1;e2)
E-If
if(tt;e1;e2)e1
E-If-T
if(ff;e1;e2)e2
E-If-F
ee
suc(e)suc(e)
E-Suc
e1e1
add(e1;e2)add(e1;e2)
E-Add-L
RawNum(n1)e2e2
add(n1;e2)add(n1;e2)
E-Add-R
RawNum(n2)
add(0;n2)n2
E-Add-Z
RawNum(n1)RawNum(n2)
add(suc(n1);n2)suc(add(n1;n2))
E-Add-S

Proposition 1.66 — Raw judgments respect alpha-equivalence

Let r,s,q be raw terms with r=αs.

  1. RawNum(r) holds if and only if RawNum(s) holds.

  2. RawVal(r) holds if and only if RawVal(s) holds.

  3. If rq by a raw rule instance, then there is a raw term q such that sq by a raw rule instance and q=αq.

Proof of Proposition 1.66 — Raw judgments respect alpha-equivalence

Proof. For item 1, induct on the raw-numeral derivation. Lemma 1.54(1) says that alpha-equivalent terms have the same outer constructor. The zero case therefore remains zero. In the successor case, inversion gives r=suc(r0), s=suc(s0), and r0=αs0; apply the induction hypothesis and reapply Num-S. Symmetry of alpha-equivalence gives the reverse implication. Item 2 is the corresponding induction on the raw-value derivation. Lambda and Boolean constructors are preserved; the numeric case uses item 1 and reapplies V-Num. Symmetry again gives the reverse implication.

For item 3, induct on the raw-step derivation and invert r=αs using the same-outer-constructor clause of definition 1.53. In each congruence case—E-App-L, E-App-R, E-If, E-Suc, E-Add-L, and E-Add-R—inversion relates the corresponding arguments by alpha-equivalence. Apply the induction hypothesis to the argument that steps, use item 1 or item 2 for the numeral or value side premise, and reapply the same rule. Congruence of alpha-equivalence relates the two targets.

For E-If-T, E-If-F, E-Add-Z, and E-Add-S, inversion preserves the Boolean or arithmetic head constructor and relates each branch or numeral component by alpha-equivalence. Items 1–2 preserve the side premises. Reapply the same root rule; the selected branch or constructed arithmetic target is alpha-equivalent to the original target by those component equalities and alpha congruence.

For E-Beta, inversion gives (λx.b)v=α(λy.c)v,λx.b=αλy.c,v=αv. Item 2 transfers the value premise. Choose a name z outside the names of all four displayed raw subterms. The common-opening clause gives bz/x=αcz/y. Together with v=αv, well-definedness of substitution gives [bz/x][[v]/z]=[cz/y][[v]/z]. Apply lemma 1.63 first to b,v,x,z and then to c,v,y,z. These two instances give the outer equalities in [b][[v]/x]=symmetryoflemma1.63[bz/x][[v]/z]=(1.2)[cz/y][[v]/z]=lemma1.63[c][[v]/y]. Choose the raw target of the right-hand E-Beta instance as q. Equality of the first and last terms in the annotated chain is exactly q=αq. The six congruence families and five root families exhaust the raw-step rules. ◻

Definition 1.61 — Values and numeric values

For quotient terms v=[r], n=[s], e=[p], and e=[q], define v valRawVal(r),n numRawNum(s),eepq by a raw rule instance for some pe, qe. Proposition 1.66 proves that these definitions do not depend on representatives. The induced quotient derivations retain the rule names V-LamNum-S and E-App-LE-Add-S. The result of a root step is its contractum.

Definition 1.63 — Call-by-value closure

The judgment ee records zero or more full call-by-value steps from e to e. It is the reflexive-transitive closure of : reflexivity permits zero steps, and transitivity joins finite chains. It is generated by the following two rules.

ee
CBV-Refl
ee1e1e2
ee2
CBV-Step

Lemma 1.64 — One-step inclusion and many-step transitivity

Every ee gives ee. If e0e1 and e1e2, then e0e2.

Proof of Lemma 1.64 — One-step inclusion and many-step transitivity

Proof. For the first claim, apply CBV-Step to the given step and CBV-Refl. For transitivity, induct on the first many-step derivation. The CBV-Refl case is the second derivation. In the CBV-Step case, retain its first one-step premise, compose its many-step tail with the second derivation by the induction hypothesis, and reapply CBV-Step. ◻

The subscript A distinguishes the arithmetic-fragment relations A and A from the full-language relations and ; a star always means reflexive-transitive closure of the corresponding unstarred relation.

Lemma 1.65 — Arithmetic rules embed in the enlarged dynamics

If eAe, then ee; if eAe, then ee.

Proof of Lemma 1.65 — Arithmetic rules embed in the enlarged dynamics

Proof. A-Suc, A-Add-L, A-Add-R, A-Add-Z, and A-Add-S have the same premises and conclusions as E-Suc, E-Add-L, E-Add-R, E-Add-Z, and E-Add-S. Induct on the one-step derivation, then on the arithmetic M-Refl/M-Step many-step derivation. The many-step cases replace M-Refl by CBV-Refl and M-Step by CBV-Step; every one-step premise is transformed by the first part. ◻

Let t:=(λf.fff)(λx.if(x;ff;tt)). Its first step uses E-Beta with a value argument:

λx.if(x;ff;tt) val
V-Lam
(λf.fff)(λx.if(x;ff;tt))(λx.if(x;ff;tt))ff
E-Beta

The rest is forced: tEBeta(λx.if(x;ff;tt))ffEBetaif(ff;ff;tt)EIfFtt.

Lemma 1.66 — Values are final

If v val, no judgment ve is derivable.

Proof of Lemma 1.66 — Values are final

Proof. Rule induction on the value derivation reduces the numeric case to rule induction on n num. No reduction rule has a lambda, boolean, or zero as its left-hand term. A successor numeral could step only by E-Suc, whose premise would step from its numeric predecessor, excluded by induction. ◻

Definition 1.67 — Evaluation contexts and contractions

The congruence rules locate the next computation by a stack of outer constructors. An evaluation context packages that stack as one object: it is a term-shaped expression with one hole, written [], marking the place where the next step occurs. In the grammar below the metavariable v ranges over all values and n ranges over all numerals; their side conditions are v val and n num. The grammar is E::=[]EevEif(E;e1;e2)suc(E)add(E;e)add(n;E). Write Ee for filling the unique hole, defined recursively by []e=e,Ee2e=Eee2,vEe=vEe,if(E;e1;e2)e=if(Ee;e1;e2),suc(E)e=suc(Ee),add(E;e2)e=add(Ee;e2),add(n;E)e=add(n;Ee). The hole is a metasyntactic marker, not a term constructor; plugging produces a term. No evaluation-context frame binds a variable, so plugging respects alpha-equivalence of the inserted term. A redex is the source of a basic contraction. Write r0r, read “r contracts to r,” for one of (λx.b)v0b[v/x],if(tt;e1;e2)0e1,if(ff;e1;e2)0e2,add(0;n)0n,add(suc(n1);n2)0suc(add(n1;n2)), with the value and numeral premises displayed in definition 1.65. The relation 0 records a root contraction, before any evaluation-context frame surrounds the redex.

The context decomposition below uses the arithmetic term from the first small-step calculation. Thin edges are syntax-tree edges, heavy edges mark the path selected by the evaluation context, and the dashed box encloses the basic redex.

Mathematical diagramDiagram

The heavy path consists of the frames add([];0) and suc([]). The represented equation is add(suc(add(0;suc(0)));0)=add(suc([]);0)add(0;suc(0)).

Definition 1.68 — Stuck term

A stuck term is a closed term e that is not a value and has no e with ee.

Lemma 1.69 — Unique decomposition

Every closed term is exactly one of the following:

  1. a value;

  2. Er, for a unique evaluation context E and a unique source r of a basic contraction;

  3. a stuck term.

Moreover ee exactly when e=Er, r0r, and e=Er.

Proof of Lemma 1.69 — Unique decomposition

Proof. The trichotomy is structural induction on the closed term. Every immediate subterm visited below is closed because the complete term is closed; the induction never descends under an abstraction. Constants, abstractions, and numeral successors are values. For an application e1e2, decompose e1. If it contains the unique redex r in context E, then the application contains that redex in context Ee2. If e1 is stuck, so is the application. If e1 is a value, decompose e2 and use the frame e1E when it steps. When both are values, the application is a beta redex exactly when e1 is an abstraction; a boolean or numeral in function position is stuck.

For conditionals, successors, and additions, the corresponding context frames select the leftmost argument that can step. Once both addition arguments are numeric, the first is uniquely either 0 or suc(n), selecting one root contraction. A final but nonnumeric argument of suc or add makes the complete term stuck. A conditional with a final guard other than tt or ff, such as if(λx.x;e1;e2), is likewise stuck.

Uniqueness. Prove the strengthened property U(e):e=Er=ErE=E and r=r by structural induction on the common term e. There are seven possible outer context cases: 0[]1E0e22v1E03if(E0;e1;e2)4suc(E0)5add(E0;e2)6add(n1;E0). First separate case 0 from cases 1–6. Every earlier call-by-value position of a basic redex contains a value: these are the operator and argument of a beta redex, the guard of a conditional redex, and the required numeric arguments of an addition redex. If one of those values were instead E0r0, induction on E0 would lift the basic contraction of r0 to a step of that value, contradicting lemma 1.66. Hence case 0 cannot compete with cases 1–6.

Now compare two nonempty cases. Cases 1 and 2 are separated by whether the operator is already a value: an operator of the form E0r0 with nonempty E0 can step and hence is not a value. Cases 5 and 6 are separated by whether the left operand is already a numeral. Cases 3 and 4, and the application and addition families, have distinct outer constructors. Thus the two decompositions use the same outer frame. Remove that frame and apply the induction hypothesis U to obtain the same inner context and basic redex. In case 0, both decompositions give r=e=r directly. Therefore E=E and r=r in all seven cases.

For the final assertion, induction on a step derivation extracts the context: each congruence rule adds its corresponding frame, and each computation rule uses the empty context. Conversely, induction on E lifts the basic contraction by the corresponding congruence rule. The beta case uses proposition 1.60 to identify contracta obtained from different fresh representatives. ◻

Theorem 1.70 — Determinism of call-by-value reduction

If ee1 and ee2, then e1=e2 as terms.

Proof of Theorem 1.70 — Determinism of call-by-value reduction

Proof. By lemma 1.69, both steps expose the same context and the same basic redex. Each basic redex has one contractum: the two conditional heads are disjoint, the two addition heads are disjoint, and capture-avoiding substitution is a function on alpha-classes by proposition 1.60. Filling the common context gives e1=e2. ◻

Exercise 1.15

★★☆ Give the evaluation context and basic redex at each step of (λx.add(x;suc(0)))(add(0;suc(0))). Then replace the argument by λy.y. Show that its single beta step produces add(λy.y;suc(0)), which is in clause 3 of lemma 1.69.

Definition 1.71 — Big-step evaluation

The big-step judgment ev relates a term directly to its final value. It is generated by

v val
vv
B-Val
e1λx.be2v2b[v2/x]v
e1e2v
B-App
ette1v
if(e;e1;e2)v
B-If-T
effe2v
if(e;e1;e2)v
B-If-F
enn num
suc(e)suc(n)
B-Suc
e1n1e2n2sum(n1;n2;n3)
add(e1;e2)n3
B-Add

The numeral premise in B-Suc excludes a final nonnumeric value under suc. The stuck term ttff matches the source shape of B-App, but its required premise ttλx.b has no derivation: final-rule inspection of an evaluation whose source is tt leaves only B-Val, whose result is tt. Matching a rule’s conclusion shape is therefore not enough to derive its premises. This full-language judgment is distinct from A. For arithmetic expressions e and numerals n, the exact comparison is eAn if and only if en, as proved in lemma 1.73.

Lemma 1.72 — Full big-step results are values

If ev, then v val.

Proof of Lemma 1.72 — Full big-step results are values

Proof. Use rule induction on the big-step derivation. The B-Val premise is the required judgment. In B-App, use the induction hypothesis for the third evaluation premise. In B-If-T and B-If-F, use the induction hypothesis for the selected branch. In B-Suc, Num-S changes the premise n num to suc(n) num, and V-Num gives the required value judgment. In B-Add, lemma 1.27, lemma 1.37 give n3 num from the sum premise, and V-Num concludes n3 val. ◻

Lemma 1.73 — Agreement on arithmetic expressions

For every arithmetic expression e and numeral n, eAnen.

Proof of Lemma 1.73 — Agreement on arithmetic expressions

Proof. For the forward implication, use rule induction on the arithmetic big-step derivation. In AB-Z, derive 0 val by V-Num(Num-Z) and apply B-Val. In AB-S, the induction hypothesis gives the premise evaluation and lemma 1.44 gives its numeric result; apply B-Suc. In AB-Add, retain the sum premise, transform both evaluation premises by the induction hypotheses, and apply B-Add.

For the reverse implication, induct on the full big-step derivation while assuming its source has the arithmetic grammar. In B-Val, inversion of the value derivation excludes lambdas and booleans, so the source and result are the same numeral; apply lemma 1.45. Rules B-App, B-If-T, and B-If-F have nonarithmetic source constructors and therefore cannot be the final rule. In B-Suc, the source premise is again arithmetic; apply the induction hypothesis and then AB-S. In B-Add, both source premises are arithmetic. From the retained sum(n1;n2;n3) derivation, lemma 1.27 gives n1 nat and n2 nat, and lemma 1.37 converts both judgments to num. The induction hypotheses therefore transform the two evaluation premises; retain the sum derivation and apply AB-Add. ◻

For the running term t, the complete big-step derivation is Xλf.fff valVLamλf.fffλf.fffBValXλx.if(x;ff;tt) valVLamλx.if(x;ff;tt)λx.if(x;ff;tt)BValXλx.if(x;ff;tt) valVLamλx.if(x;ff;tt)λx.if(x;ff;tt)BValXff valVFalseffffBValXff valVFalseffffBValXtt valVTruettttBValif(ff;ff;tt)ttBIfF(λx.if(x;ff;tt))ffttBApptttBApp.

Lemma 1.74 — Many-step congruence

If ee, then EeEe for every evaluation context E.

Proof of Lemma 1.74 — Many-step congruence

Proof. First induct on the many-step derivation for a one-frame context, lifting each first step by the frame’s congruence rule. Then induct on the grammar of E, applying the one-frame result at the outer frame and the context induction hypothesis inside it. ◻

Theorem 1.75 — Big step implies small steps

If ev, then ev.

Proof of Theorem 1.75 — Big step implies small steps

Proof. Use rule induction on the big-step derivation. The B-Val case is CBV-Refl. For B-App, V-Lam proves λx.b val, so (λx.b)[] is an evaluation context. The first induction hypothesis lifts through []e2, and the second lifts through (λx.b)[]. Moreover, lemma 1.72 applied to the second evaluation premise gives v2 val, the side premise for E-Beta. The three induction hypotheses therefore give e1e2IH1+lemma1.74(λx.b)e2IH2+lemma1.74(λx.b)v2EBetab[v2/x]IH3v. Lemma 1.64 turns the one-step segment into a many-step derivation and composes the four annotated segments. If the big-step derivation ends in a true conditional, its test induction hypothesis gives e0tt, contextual closure gives if(e0;e1;e2)if(tt;e1;e2), E-If-T contracts to e1, and the selected-branch induction hypothesis reaches the result; the false case uses E-If-F and the hypothesis for e2. The successor hypothesis lifts through suc by lemma 1.74. In the addition case, the last big-step premise is sum(n1;n2;n3). By lemma 1.27, lemma 1.37, both n1 num and n2 num; in particular, add(n1;[]) is an evaluation context. Hence add(e1;e2)IH1+lemma1.74add(n1;e2)IH2+lemma1.74add(n1;n2)lemma1.47,lemma1.65n3. ◻

Corollary 1.81 — Stuck terms do not evaluate

If e is stuck, there is no term v with ev.

Proof of Corollary 1.81 — Stuck terms do not evaluate

Proof. Suppose ev. By theorem 1.75, ev. Since a stuck term has no one-step reduct, final-rule inspection leaves only CBV-Refl; hence e=v. But lemma 1.72 makes v a value, contradicting the definition of a stuck term. ◻

Lemma 1.82 — A value evaluates only to itself

If w val and wv, then v=w.

Proof of Lemma 1.82 — A value evaluates only to itself

Proof. By theorem 1.75, the evaluation gives wv. Induct on this many-step derivation. The CBV-Refl case gives v=w. The CBV-Step case would begin with a step from the value w, contradicting lemma 1.66. ◻

Lemma 1.83 — One-step expansion of big-step evaluation

If ee and ev, then ev.

Proof of Lemma 1.83 — One-step expansion of big-step evaluation

Proof. Use rule induction on ee. Six congruence cases share one reconstruction. Invert the target evaluation, replace the displayed premise by the induction hypothesis, and reapply the same big-step rule: step ruletarget’s final rulepremise replacedEAppLBAppe1λx.be1λx.bEAppRBAppe2v2e2v2EIfBIfT or BIfFe0qe0qESucBSucenenEAddLBAdde1n1e1n1EAddRBAdde2n2e2n2. Here q is tt or ff, as selected by the final conditional rule. The only extra final-rule possibility occurs for E-Suc: the target evaluation may end in B-Val. Its inversion gives e num. Rules V-Num and B-Val give ee; the induction hypothesis and then B-Suc derive suc(e)suc(e), the target of the assumed B-Val derivation.

For E-Beta, the assumed target evaluation is b[v2/x]v. Rule B-Val derives evaluations of λx.b and of the premise value v2 to themselves; these two derivations and the assumed target evaluation form B-App. The E-If-T case combines tttt, by B-Val, with the assumed evaluation of the selected branch and applies B-If-T. The E-If-F case uses V-False, B-Val, and B-If-F.

In E-Add-Z, the premise n2 num makes n2 a value. Hence lemma 1.82 changes the assumed n2v to v=n2. Rules B-Val derive 00 and n2n2; by lemma 1.37, n2 nat, so Sum-Z and B-Add derive add(0;n2)n2.

In E-Add-S, the target suc(add(n1;n2)) is not a value: inversion of a hypothetical numeral derivation would require add(n1;n2) num, but no numeral rule concludes an addition. The assumed target evaluation therefore ends in B-Suc, with add(n1;n2)q,q num,v=suc(q). Inverting the first premise gives n1p1, n2p2, and sum(p1;p2;q). The two numeral premises of E-Add-S make n1,n2 values, so lemma 1.82 gives p1=n1 and p2=n2. Rule Sum-S gives sum(suc(n1);n2;suc(q)). Together with the B-Val evaluations of suc(n1) and n2, rule B-Add derives the required source evaluation to v=suc(q). ◻

Theorem 1.84 — Small steps to a value imply big-step evaluation

If ev and v val, then ev.

Proof of Theorem 1.84 — Small steps to a value imply big-step evaluation

Proof. Induct on ev. In CBV-Refl, apply B-Val to the assumed value judgment. In CBV-Step, the induction hypothesis turns the many-step tail into e1v; apply lemma 1.83 to the first step. ◻

Corollary 1.85 — Agreement of full big-step and small-step evaluation

For all terms e,v, evev  and  v val.

Proof of Corollary 1.85 — Agreement of full big-step and small-step evaluation

Proof. The forward implication is theorem 1.75, lemma 1.72. The reverse implication is theorem 1.84. ◻

Renaming and substitution of evaluations

The E-Beta reduction step may rename a binder before substituting the argument. The chosen name must not affect the reduct. The first required fact is that fresh renaming commutes with substitution.

Lemma 1.76 — Fresh renaming commutes with substitution

Let b,v be raw terms. Let x,y,z be pairwise distinct, and suppose zNames(b)Names(v),yNames(v). Then [bz/x][[vz/x]/y]=[b][[v]/y]z/x.

Proof of Lemma 1.76 — Fresh renaming commutes with substitution

Proof. The right-hand quotient renaming is defined: if yFV(b), substitution fixes [b]; otherwise the free-variable equation in proposition 1.60 excludes z from the result. Choose b0=αb whose bound names avoid {x,y,z}Names(v). Lemma 1.54(1) gives FV(b0)=FV(b), so the hypothesis on z gives zNames(b0). Replacing b by b0 changes neither side, by definition 1.59, proposition 1.60. Use structural induction on b0. For a variable u, there are three cases. If u=y, both sides are [v]z/x=[vz/x]. If u=x, both sides are [z] by pairwise distinctness of x,y,z. Every other variable is fixed. Constants are fixed, and each nonbinding constructor follows by applying the induction hypothesis to its arguments.

For an abstraction λu.c, our representative satisfies u{x,y,z} and uNames(v). Both operations therefore pass under the same binder. The induction hypothesis gives [cz/x][[vz/x]/y]=[c][[v]/y]z/x. Reattaching λu gives the required equality of alpha-classes. Independence of the chosen representative is proposition 1.60. ◻

Lemma 1.77 — Renaming evaluation derivations

Let e,e,v,n be quotient terms. If zFV(e)FV(e) and ee, then ez/xez/x. If zFV(v) and v val, then vz/x val. If zFV(n) and n num, then nz/x num.

Proof of Lemma 1.77 — Renaming evaluation derivations

Proof. If x=z, the freshness hypotheses imply that x is absent from every chosen fresh representative. The absent-source equation reduces each conclusion to its original derivation. Assume henceforth that xz.

First use rule induction on n num to prove nz/x=n. Fresh renaming fixes 0, and the Num-S induction hypothesis gives the equality beneath suc. Thus the renamed term retains the original numeral derivation. Next use rule induction on v val. The Boolean rules are fixed by renaming, and the V-Num case uses the numeral result just proved. In V-Lam, choose a raw representative λy.b with all its bound names outside {x,z}, as permitted by lemma 1.56; its renaming is still an abstraction, so V-Lam applies.

Finally use rule induction on ee. In E-App-L, E-If, E-Suc, and E-Add-L, apply the step induction hypothesis to the unique step premise and reapply the same rule. Rule E-App-R also uses the value-renaming result for its function premise. Rule E-Add-R uses the numeral-renaming result for its left premise. Renaming fixes the Boolean heads in E-If-T and E-If-F; it also fixes the numeral shapes in E-Add-Z and E-Add-S, whose numeral premises follow from the numeral-renaming result.

In E-Beta, choose a raw representative v0 of the argument whose bound names avoid {x,z}. Next represent the abstraction as λy.b with every bound name outside {x,z}Names(v0). Since z is absent from the free variables of the source, these choices give zNames(b)Names(v0),yNames(v0). The value-renaming result proves [v0]z/x val. The renamed source contracts to [bz/x][[v0z/x]/y]. By lemma 1.76, [bz/x][[v0z/x]/y]=[b][[v0]/y]z/x. Thus the target is the required renamed contractum. ◻

Lemma 1.78 — Substitution of evaluation derivations

If ee, then e[a/x]e[a/x]. If v val or n num, then respectively v[a/x] val or n[a/x] num.

Proof of Lemma 1.78 — Substitution of evaluation derivations

Proof. First use rule induction on n num to prove n[a/x]=n. Substitution fixes 0, and the Num-S induction hypothesis gives the equality beneath suc. Thus the substituted term retains the original numeral derivation. Next use rule induction on v val. Substitution fixes both Boolean values, and the V-Num case uses the numeral result just proved. In V-Lam, choose a raw representative λy.b with y{x}FV(a). Substitution produces λy.b[a/x], so V-Lam applies.

Now use rule induction on ee. Rules E-App-L, E-If, E-Suc, and E-Add-L use the step induction hypothesis and reapply the same rule. Rule E-App-R also uses the value-substitution result; E-Add-R also uses the numeral-substitution result. Substitution fixes the Boolean heads of E-If-T and E-If-F and the numeral terms of E-Add-Z and E-Add-S; reapply those four root rules.

For one E-Beta instance, choose its abstraction representative λy.b with y{x}FV(a). This choice changes neither the source alpha-class nor its contractum, by proposition 1.60. Substitution sends the source to (λy.b[a/x])v[a/x]. The value component of the preceding induction proves that v[a/x] is a value, so E-Beta applies with target b[a/x][v[a/x]/y]. Equation 1.1, used with the roles of x and y interchanged and with yFV(a), gives b[a/x][v[a/x]/y]=b[v/y][a/x], which is the substituted target of the original step. ◻

Exercise 1.16

★★☆ Start with the E-Beta derivation of (λy.xy)ttxtt. Substitute λz.z for x, give the new derivation, and reduce its target one further step. Repeat with the original binder also named z, first alpha-renaming that binder to a name outside {x,z}FV(λz.z).

What evaluation cannot prevent

Example 1.79 — A closed stuck term

The term ttff is closed and is not a value. Its function and argument cannot step, so neither application congruence rule applies; its function is not an abstraction, so it is not a beta redex. Hence it is stuck. The term suc(λx.x) is stuck for the same structural reason: the argument is final but not numeric.

Stuckness is not nondeterminism: theorem 1.70 says that every available next step is unique. It is not divergence either. Divergence is the existence of an infinite sequence of steps beginning at a term; that term continues to step, whereas ttff has no first step. The evaluator discovers the defect only after the offending term is reached. The next problem is therefore static: construct a judgment that rejects such shape mismatches before the program is run, and prove that every accepted closed program is either a value or can take another step.

Suggested first pass.

Work exercise 1.17, exercise 1.18, exercise 1.19 as a two-hour live seminar.

Exercise 1.17

★☆☆ Let ω:=λx.xx. Show that ωωωω, so it diverges but is not stuck. Then prove that (λx.tt)(ttff) is stuck under call by value even though substituting its unevaluated argument into the body would discard the defect.

Exercise 1.18

★★☆ Reconstruct the proof of lemma 1.66 as a complete rule induction. For each final value rule, list the reduction rules whose left-hand term cannot match, and explain why raw structural induction is less precise in the numeric case.

Exercise 1.19

★★☆ Delete E-Suc and show that the rule from ee to suc(e)suc(e) is no longer admissible: give one derivable premise with an underivable conclusion. Restore E-Suc and give the one-case transformation proving admissibility.

Exercise 1.20

★★★ Prove that if eAn and n num, then eAn. First prove, by induction on the one-step derivation, that eAe and eAn imply eAn. Then prove, by induction on the many-step derivation, that eAn and n num imply eAn. Treat every arithmetic step rule in the first induction.

Exercise 1.20

★★★ Practical project.ulc-evaluator Using the Kappa scaffold specified in the practical tutorial, spend four to six hours implementing the call-by-value one-step relation of definition 1.62. Implement free-name calculation, fresh-name selection, capture-avoiding substitution, one-step reduction, and fueled iteration. Maintain the invariant that a returned raw beta target q for (λx.b)v satisfies [q]=[b][[v]/x]. Distinguish values, closed stuck terms, open nonvalues with no step, and fuel exhaustion.

Test every rule family. Add a substitution mutant that omits freshening and test it on (λ0.λ1.0)(λ2.1): name 1 must remain free in the correct contractum but becomes bound in the mutant’s result. The remaining tests must reduce the term t defined in equation 1.3 to tt, classify ttff as stuck, and exhaust ten units of fuel on ωω. Place each test source beside its selected rule and expected target. State why the corpus proves none of alpha compatibility, determinism, or divergence for all terms.

Search the book

Type to search the local edition.