Again write for bracket abstraction. In combinatory logic, all variable occurrences are free variables. Under and , substitution for preserves the presence or absence of :
An existing is not replaced because ; replacing cannot introduce an because contains none. This ensures that the same clause of bracket abstraction applies before and after substitution.
Use structural induction on , respecting those clauses. If , then
because substitution leaves the S combinator, the K combinator and unchanged.
If is absent from , it is also absent from . Therefore
This includes : even when is a large application, the absence of means bracket abstraction still produces .
Finally, let with occurring in or . By the occurrence observation, also occurs in or , so the application clause applies on both sides. Apply the induction hypotheses:
Every step uses the definitions of substitution and bracket abstraction, without applying the equality axioms for the S combinator or the K combinator. Thus the result is the stronger syntactic identity
The side condition on is essential for this identity. For example, substituting for in gives , whereas , a different string.
Root the tree arbitrarily. For each vertex , let be the minimum vertex cover size in its descendant subtree, conditional on selecting , and the corresponding minimum conditional on omitting . Process the vertices in postorder traversal. For every child of ,
At a leaf of a rooted tree, the empty sums give . Return at the root .
For algorithm correctness, if is selected, each child subtree may independently use its cheaper state, since the connecting edge is already covered by . If is omitted, each child must be selected to cover its connecting edge. Distinct child subtrees have no edges between them because the input is a tree. These observations prove the recurrences by structural induction. Each edge contributes constant work once, giving time complexity and space with adjacency lists. The single-vertex tree correctly has optimum zero. This is minimum vertex cover of a tree by dynamic programming.
A Boolean valuation is an arbitrary function assigning one of the two truth values to each propositional variable. It extends uniquely to all propositional formulas by following the construction of the propositional formula:
For logical implication, is false exactly when is true and is false; otherwise it is true. Here the operations on the right are Boolean operations on truth values. Structural recursion gives existence, and structural induction gives uniqueness: once the immediate subformulas have their values, the outer connective fixes the resulting value.
Use structural induction on the formation of a propositional formula. A propositional variable has no parentheses. Applying negation to a logical formula adds no parentheses, so preserves equality of the two counts. If and each have equally many opening and closing parentheses, the formation of adds one of each to their combined counts. Thus every propositional formula satisfies
This is a necessary condition for being a logical formula; it is not sufficient, since the logical connectives and the placement of symbols must also follow the formation rules.
Fix the particular occurrence of that is being replaced. The subformula analysis above makes it a node of the formula syntax tree of . Proceed by structural induction on the surrounding logical formula.
If this node is the root, the subformula replacement gives , already a logical formula. Otherwise, if , the chosen occurrence lies inside . The induction hypothesis gives a logical formula after the subformula replacement there, and the whole result is the logical formula . If , a proper chosen occurrence lies in exactly one of the two children. Replacing inside that child gives either or , each a logical formula by the formation rule. A logical variable has no proper subformula, so there is no additional base case.
Therefore replacing the designated subformula occurrence by any logical formula preserves well-formedness. The argument concerns one chosen occurrence; it does not require simultaneous subformula replacement of every occurrence of the same string.
Translate logical formulas recursively, leaving propositional variables unchanged and translating negation by applying negation to the translation. For the other two logical connectives set
The first logical implication is false exactly when both original inputs are false; the second displayed logical formula is true exactly when both inputs are true. Hence each clause preserves truth values. Structural induction gives for every Boolean valuation and every logical formula in the larger language.
By the assumed functional completeness of negation, logical conjunction and logical disjunction, any finite Boolean function has such a logical formula . Its translation uses only negation and logical implication and represents the same function. Thus is adequate.
For a standard classical propositional calculus, strong completeness states
Together with soundness, this identifies semantic consequence with formal derivability. One proves the contrapositive by the maximal consistent set in propositional logic construction. If , the set is propositionally consistent, by the deduction theorem for propositional logic and classical propositional reasoning. Extend it to a maximal consistent set in propositional logic , deciding each logical formula in turn. At each stage at least one selection of or preserves propositional consistency; a contradiction in the union would use only finitely many assumptions and hence already occur at a stage.
Define a Boolean valuation by exactly when . Maximal consistency in propositional logic gives exactly when , and exactly when either or . Structural induction on logical formulas therefore proves the maximal consistent set truth lemma . Thus satisfies but falsifies , contradicting semantic entailment. The countable language here permits an enumeration of logical formulas; the corresponding general-language argument uses a well-ordering or a principle of maximality in a partially ordered set.
Capture-safe equality replacement gives the corrected scheme:
where replaces selected free occurrences of by , without capture. One may equivalently use full capture-avoiding substitution, after renaming conflicting binders. Replacing bound occurrences as though they were free is not permitted.
Here is a syntactic proof. Write for . First derive symmetry under : A6 and A4 give , and A7 applied to the first position in that atomic equality gives . Modus ponens and the deduction theorem give . Atomic replacement in the forward direction is A7 itself; in the reverse direction apply A7 with exchanged and use this symmetry. Thus under , an atomic formula and its designated replacement imply each other.
Induct on the formation of , proving both directions simultaneously. For negation, the reverse implication for the immediate subformula gives the forward implication of its negations by contraposition, and vice versa. For , the two induction equivalences combine propositionally to . This uses only the propositional tautologies allowed in this part.
For , first take distinct from . From assumptions and , A4 gives , the induction hypothesis gives , and generalization gives : is free in neither open assumption. Discharge the two assumptions to obtain . The reverse direction is identical. If the binder is , no free occurrence of that variable lies beneath it and the replacement there is empty. If it is , capture avoidance likewise forbids a changed free below that binder unless the binder is first renamed to a fresh variable. Bound-variable renaming is derived from A4 followed by admissible generalization and A5, with the same freshness restriction. This completes the structural induction and proves the scheme for arbitrary formulas.
True. In the formation rules, commas occur only between arguments in a function application or an atomic predicate application. Each such argument list includes an opening parenthesis. Subsequent construction of larger terms or formulas retains those symbols.
Equivalently prove by simultaneous structural induction on terms and formulas that an expression containing no opening parenthesis contains no comma. Variables and constants have neither; a comma-bearing function or predicate application already has an opening parenthesis; equality, connectives, and quantifiers cannot introduce a comma outside their constituent expressions. Taking the contrapositive proves the claim.
Use structural induction on formulas. Every term denotes the unique element. Every atomic predicate is true by hypothesis, and every equality is true because its two terms denote that same element.
If both immediate subformulas of an logical implication are true, their logical implication is true. A universal or existential quantification ranges over the singleton domain; its matrix is true for the only possible value by induction, so either quantified formula is true. These are all the formation cases in the reduced language. Hence
First eliminate implication and biconditional using the logical equivalences
Push negations inwards using De Morgan's laws and eliminate double negations. Structural induction leaves only literals joined by conjunction and disjunction.
Now induct on that remaining expression. A literal is already in conjunctive normal form. A conjunction of two conjunctive normal forms is again one after associating its clauses. For a disjunction, write the two inductively obtained forms as and and use distributivity:
Each is a clause. All operations preserve logical equivalence, proving the required form exists.
Write for the reflexive closure of the transitive closure of a relation , and for its generated equivalence relation. The diamond property requires every pair to admit a one-step join . The Church-Rosser property requires a possibly longer join whenever . Equivalently, every pair of finite reductions with the same source has a common finite reduct. Identity steps may be included in the diamond convention without affecting the counterexample below.
Let and consider the lambda term . Contracting its outer beta-redex gives , whereas contracting the inner beta-redex gives . The only one-step reducts of are and ; the other branch has the sole one-step reduct . These terms are different even under alpha equivalence. Thus one-step beta reduction has no diamond property. Both branches do reach by finite beta reduction.
For the positive result, use parallel beta reduction , with rules
Structural induction, renaming binders to avoid capture, proves the substitution lemma: and imply . Define the complete development of a lambda term by
and when the application is not initially a root beta-redex. Induction on a parallel derivation, using the substitution lemma in the contracting case, proves
Consequently any two parallel reducts have the common successor . The ordinary one-step relation is included in the parallel relation, and every parallel step expands into finitely many ordinary steps; their finite closures therefore coincide. A finite grid of parallel diamonds joins any two finite parallel reductions. Finally a finite zigzag of forward and backward reductions can be joined inductively using that confluence. Hence beta reduction has the Church-Rosser property, although its individual steps do not have the diamond property.
The two different term letters in the printed implication must be made consistent; write the indexed step as . An indexed lambda term in is a finite lambda term with a bottom constant , together with a natural-number index at every subterm occurrence. Equal-looking subterms at different occurrences can have different indices. Bottom here is a constant, not an abbreviation for the divergent Omega combinator.
For , write ; in particular can contain zero. Use the graph model of lambda calculus and its pairing code from the preceding solution. If the root index is , interpretation is recursive:
Thus every constructor is clipped at its own occurrence index, not merely at the overall root.
Here are the indexed beta reduction rules. In , substitute a copy of at each free occurrence with that copy's root index lowered to . Lower the substituted body's root index further by taking its minimum with ; other inherited indices remain unchanged. If the entire body is , this retains the root bound of the inserted argument as well. For an abstraction with index zero, substitute for instead and lower the resulting body root index to zero. The previous root index on the redex application need not be retained. Reduction is allowed in all contexts. Bottom reduction additionally collapses and to ; one can collapse the whole maximal abstraction/left-application context in which an occurrence of bottom is at the head. These rules are sensitive to the pairing and cutoff conventions just specified.
To prove semantic monotonicity, first check the finite-witness bounds, writing for graph application:
For the first bound, a witness has . If , the pairing code is strictly larger than ; for the assertion is automatic. Also every member of satisfies , hence . So the same witness uses only . For the zero-index case the sole possible graph entry is , whose finite-input witness is .
Let and . A syntax induction gives the indexed substitution equality: replacing by a copy of with root interprets that occurrence as , exactly its value when the bound variable receives . The body-root change to clips the resulting body value at . Hence the positive-index contractum has interpretation , while the redex before contraction is included in that set by the finite-witness bound. In the zero-index case the contractum interprets as , equal to the un-clipped application of the zero-indexed abstraction. The old application-root cutoff can only decrease the redex value. Bottom contractions preserve the empty interpretation: the empty graph applied to anything is empty, and abstraction with an everywhere-empty body has empty graph. All surrounding interpretation constructors are monotone. Therefore
For the unindexed erasures, indexed positive contractions are ordinary beta contractions, whereas zero-index contractions first discard their argument by replacing it with bottom. Consequently the result contains no new Böhm information:
where permits replacement of subtrees by bottom and identifies bound names. To justify this syntactically, replacement of subterms by bottom commutes monotonically with substitution. A contraction in a partially erased term can be lifted to the corresponding contraction in the original term; if an erased function-head prevents matching a contraction, its result is bottom and is still below the original subtree. Induction over a finite reduction sequence therefore exhibits the erasure of as a partial reduct of a beta-equivalent version of . Bottom contractions only prune this partial tree. Ordinary beta contractions alone preserve the Böhm tree; the extra pruning explains why semantic inclusion here has the opposite orientation to the tree comparison.
Let be the finite Böhm approximants of . Their grammar is
Equivalently, they are finite beta-bottom normal forms obtained from a term beta-equivalent to by replacing subterms by bottom. The approximation theorem for the graph model is
Here is a full proof. First, every indexed interpretation lies below the unindexed one. Increasing any occurrence index can only increase it, so the indexed interpretations form a directed family. Their union is the unindexed interpretation:
Prove this by structural induction. It is immediate for variables and bottom. At application, membership of an output has one finite-input witness in the graph; structural induction captures its graph entry and the finitely many required argument entries at finite child indices, and a root index at least the output captures it. At abstraction, a graph entry is determined by one body membership in the finite-input environment ; structural induction captures that membership at finite body indices, and a root index at least captures the entry. This proves both inclusions in the union identity without assuming the approximation theorem.
Now fix and reduce the fully indexed term to its normal form , using the permitted normalization hypothesis. Its erasure has neither a beta redex nor a bottom-headed abstraction/application, so has the displayed approximant grammar. The lifting and pruning argument above gives . The semantic inequality along its finite reduction sequence gives
Taking the union over proves inclusion of the left side of the approximation theorem in the right. For the reverse inclusion, choose and a beta-equivalent term from which it is obtained by erasing subterms. Beta soundness gives that term the same interpretation as ; erasure replaces interpretations by the least element, and every semantic constructor is monotone. Thus . Taking the union finishes the proof. In particular an unsolvable lambda term has only the bottom approximant and therefore has empty interpretation in .
An ultraproduct assembles a family of nonempty first-order structures in one fixed language, using an ultrafilter to specify which coordinate statements hold almost everywhere. Its universe is
Functions are interpreted coordinatewise, and an -ary relation holds on when its coordinate truth set belongs to . Changing representatives changes such a truth set only off a -large set, so these definitions are well defined. A principal ultrafilter simply recovers its distinguished factor; a nonprincipal ultrafilter can produce new elements and structures.
The fundamental result is the Łoś theorem:
Prove it by structural induction on first-order formulas. Atomic formulas are the definition. Intersections handle conjunction, while exactly one of a set and its complement belongs to an ultrafilter, handling negation. For the existential step, if the coordinate existential truth set is in , use choice to select witnesses there and arbitrary values elsewhere; their product function is an ultraproduct witness. Conversely a product witness makes the coordinate existential truth set contain a -large set. Other connectives and universal quantification follow.
In an ultrapower, all factors are one structure . The diagonal map is an elementary embedding by the Łoś theorem. For a nonprincipal on , the class of in an ultrapower of the standard natural numbers is larger than every constant natural number, since each tail belongs to . This gives a nonstandard model of Peano arithmetic. Similarly, an ultraproduct of finite fields with distinct primes tending to infinity has characteristic zero: for every fixed positive integer , the equation fails in all sufficiently late factors. An infinite structure can therefore arise from finite factors.
Ultraproducts prove the compactness theorem. If each finite subset of a theory has a model , index these models by . The cones have the finite intersection property. Extend their filter to an ultrafilter using the ultrafilter lemma. The Łoś theorem makes the resulting ultraproduct satisfy every . This construction also gives elementary extensions realizing prescribed finitely satisfiable types.
A useful stronger property is countable saturation of an ultraproduct over omega. Let a countable type be finitely satisfiable in an ultraproduct over a nonprincipal on . Choose coordinate representatives of its parameters. Let be the coordinates where the first formulas have a simultaneous witness; then , the decrease, and we can replace by . At coordinate , choose a witness to the first formulas, where is the largest with , taking an arbitrary value if there is none. For each fixed , the set where is -large. Its class realizes the entire type. This proof uses countable incompleteness of , not arbitrary completeness or automatic saturation at larger cardinals.
Finally, complete ultrafilters connect ultraproducts to large cardinals. A countably complete ultrafilter prevents an externally infinite descending membership chain in an ultrapower of a well-founded universe: intersect the countably many coordinate truth sets and obtain an impossible descending chain at one coordinate. A kappa-complete nonprincipal ultrafilter on consequently supplies the ultrapower embedding associated with a measurable cardinal. Thus the same construction supports both elementary compactness arguments and large-cardinal embeddings, with the completeness hypothesis deciding which well-foundedness and closure properties survive.
Generate every permutation of the tail, then insert its missing head at every possible position. The helper preserves order among the elements already present:
sml
fun insertEverywhere x [] = [[x]]
  | insertEverywhere x (y :: ys) =
      (x :: y :: ys) ::
      List.map (fn zs => y :: zs) (insertEverywhere x ys);

fun permutations [] = [[]]
  | permutations (x :: xs) =
      List.concat
        (List.map (insertEverywhere x) (permutations xs));
The first helper result inserts before ; the mapped recursive results put back at the front and insert farther along. For a list of length , it yields exactly positions. The empty list has one permutation, itself, so the base result is [[]], not [].
For correctness, use structural induction. Any permutation of x :: xs has a unique position containing . Removing that position leaves a permutation of xs, supplied by the induction hypothesis; reinserting at its unique position reconstructs the required output. With distinct input elements, neither the tail permutation nor the insertion position can be duplicated, so each output occurs once. Consequently a length- input yields exactly permutations, in an unrestricted order. The explicit output is large; this is not a polynomial-time enumeration with respect to alone.
Introduce a checked exception class, for example in its own source file:
public final class ItDoesDependOn extends Exception {
    private final MLType.TypeVar variable;
    public ItDoesDependOn(MLType.TypeVar variable) {
        this.variable = variable;
    }
    public MLType.TypeVar getVariable() { return variable; }
}
Declare the required abstract method in MLType:
public abstract void mustNotDependOn(TypeVar a)
    throws ItDoesDependOn;
Within the nested TypeVar class implement it by an identity check:
public void mustNotDependOn(TypeVar a) throws ItDoesDependOn {
    if (this == a) throw new ItDoesDependOn(a);
}
Within the nested Arrow class implement it recursively:
public void mustNotDependOn(TypeVar a) throws ItDoesDependOn {
    from.mustNotDependOn(a);
    to.mustNotDependOn(a);
}
The parameter denotes an actual non-null type variable returned by the factory; checking object identity distinguishes different variables without confusing their printed names. Structural induction on the abstract syntax tree proves the occurs check: a variable node contains the queried variable exactly when the identities match, and an arrow contains it exactly when either component does. The first detected occurrence throws and propagates the checked exception; normal return proves absence. Both subclass methods must declare the exception, and callers must catch or declare it.
For , either recursive branch detects each of , whereas a distinct is absent and the call returns. A recursive identity-based occurs check throws exactly when the queried variable occurs.
For integer linked lists, compare their heads and copy the smaller head, retaining the other list for the next step:
fun merge ([], ys) = ys
  | merge (xs, []) = xs
  | merge (xs as x :: xt, ys as y :: yt) =
      if x <= y then x :: merge (xt, ys)
      else y :: merge (xs, yt);
This merge algorithm preserves duplicates and chooses the left list on a tie, making it stable when elements have an ordering key. Each recursive step decreases the combined length. For correctness, the chosen head is no greater than either remaining head and therefore no greater than any remaining element; structural induction then proves that the result is ordered and contains exactly the elements of both inputs. For other element types, replace the integer comparison by a supplied ordering function. Merge repeatedly emits the smaller head and reuses the remaining list when the other becomes empty.
Assuming p is an ordinary total Boolean predicate, replace success by true and the search's failure exception by false:
fun gordonPlain p Lf = true
  | gordonPlain p (Br (x, left, right)) =
      p x andalso
      (gordonPlain p left orelse gordonPlain p right);
The Standard ML handler in the printed function belongs to the else expression: it tries the left subtree and, only if that search raises Blair, tries the right. It does not catch a failing label test at the current node. This scope follows the Standard ML grammar, Appendix B. Short-circuit andalso rejects the current label before visiting either child; short-circuit orelse visits the right child only after the left search fails. Structural induction on the binary tree proves that tony returns true exactly when gordonPlain does, and otherwise raises the exception converted by gordon to false. The exception-free test is the root predicate conjoined with the disjunction of the two subtree tests.
The total-predicate assumption matters: if p itself raises Blair, the original handler can catch it, whereas an implementation with no exception handling cannot in general convert that event to a Boolean result. The displayed replacement implements the intended Boolean tree property, not an exception-catching wrapper for arbitrary exceptional predicates.
Carry the list as an immutable accumulator instead of storing it in a reference:
fun snackerPure m =
    let
      fun collect (Snack x, acc) = x :: acc
        | collect (Lunch (a, b), acc) =
            collect (b, collect (a, acc))
        | collect (Feast (a, b, c), acc) =
            collect (c, collect (b, collect (a, acc)))
    in
      collect (m, [])
    end;
For any initial accumulator acc, structural induction shows that collect(m,acc) equals the final reference content obtained by traversing m left to right and prepending each snack to a reference initially containing acc. At Lunch and Feast, the accumulator passed to each child is the result of all earlier children, exactly matching the imperative sequencing. Thus the result is the reverse of the left-to-right list of snack labels, just as for the original snacker; returning the ordinary left-to-right list would be incorrect. The code uses no mutable cells and is polymorphic, with type 'a meal -> 'a list.
Carry the number of original snacks still to skip, returning it together with the reconstructed subtree. Zero means that the replacement has already happened:
fun glut k meal replacement =
    let
      fun visit (t, 0) = (t, 0)
        | visit (Snack x, j) =
            if j = 1 then (replacement, 0)
            else (Snack x, j - 1)
        | visit (Lunch (a, b), j) =
            let val (a1, j1) = visit (a, j)
                val (b1, j2) = visit (b, j1)
            in (Lunch (a1, b1), j2) end
        | visit (Feast (a, b, c), j) =
            let val (a1, j1) = visit (a, j)
                val (b1, j2) = visit (b, j1)
                val (c1, j3) = visit (c, j2)
            in (Feast (a1, b1, c1), j3) end
    in
      if k < 1 then raise Subscript
      else
        let val (answer, remaining) = visit (meal, k)
        in if remaining = 0 then answer else raise Subscript end
    end;
The successive bindings explicitly establish left-to-right counting. Before the target is reached, each original snack decreases the counter by one; at the target the subtree becomes replacement and the counter becomes zero. Subsequent subtrees are returned unchanged, and newly inserted snacks are never counted. Structural induction on the helper's subtree establishes this invariant and proves the specified one-based substitution. The result has type int -> 'a meal -> 'a meal -> 'a meal. Since unaltered original snacks remain, their label type must agree with the replacement's label type.
The behavior for an invalid index is not specified in the PDF; this implementation deliberately raises Subscript for or too few snacks. For valid input, exactly the th original snack in left-to-right order is replaced. Sharing untouched immutable subtrees is semantically equivalent to a fresh structural copy.