Lectures onType Theory
Chapter 112
Chapter 112Core route

Elaboration and Unification

Let Γapp:=A:Uu, m:N, n:N, xs:Vec(A,m), ys:Vec(A,n). The surface application appendxsys does not belong to the kernel language. The kernel constant expects a level, an element type, and two length indices before the two vectors: append[u]{A}{m}{n}xsys:Vec(A,n+m). The braces mark implicit term arguments and the square brackets mark an external level argument. Deleting those four arguments is harmless only if a terminating procedure reconstructs them, rejects incompatible choices, and returns the explicit term in (112.2) for the kernel to check. That reconstruction problem is elaboration.

The surface-to-core problem

The kernel checks one fixed calculus. Surface syntax changes how information reaches that calculus; it does not add a kernel rule.

Convention 112.1 — The Timpl elaboration card

This chapter inherits the predicative kernel signature Timpl, pronounced “Timpl”, from convention 110.16. Surface elaboration additionally admits level metavariables; generated level expressions use zero, successor, and maximum, and a solved elaboration instantiates them by external Timpl levels. Every core Π-binder, abstraction, and application therefore carries the explicitness and relevance bits fixed by the inherited signature. Elaboration copies both bits and never guesses either independently of a binder. The core Σ-former, pairs, and projections have no such metadata.

The chapter assumes a conversion interface providing total normalization to beta-iota normal, eta-long form, constructor inversion, and conversion for this exact signature. Eta-long form is recursive at every Timpl former with a uniqueness rule: a 1-typed term normalizes to , a Σ-typed neutral is exposed as a pair of projections whose components are normalized again, and a Π-typed neutral is exposed as an abstraction. Consequently variables of recursively contractible Unit/Sigma type disappear from canonical support rather than surviving as arbitrary neutral heads. The rules below use that interface rather than re-prove a conversion query. Theorem 111.81 constructs the six operations at the exact Timpl signature and corollary 111.82 discharges this oracle boundary. This does not make the whole elaborator total: general recursive definitions, W-types, coinduction, quotient computation, equality reflection, recursive pattern clauses, coercions, overloading, type-class search, and tactics are not in this card. In particular, the chapter reconstructs the arguments of an already elaborated vector eliminator; it does not compile the two clauses defining append.

Definition 112.2 — The surface fragment T_ elab

The surface fragment Telab has variables and declared constants; explicit and implicit Π-binders, abstractions, and applications; Σ-types, pairs, and projections; the nullary and constructor forms of 1, 2, N, identity, and Vec; strict universe expressions U; their motive-annotated eliminators; annotations (e:A); and holes written _. A fully explicit core term may occur as an annotated atom. Thus every Timpl former is available, while the only information the elaborator reconstructs is:

  1. implicit term arguments declared by an implicit Π-binder;

  2. external universe levels;

  3. the type and term demanded by a hole; and

  4. annotations forced by an expected type.

A surface Π-binder and abstraction record explicitness and relevance. Written application syntax records explicitness; its relevance is copied from the exposed Π-head. The Σ-binder carries neither bit. Surface recursive clauses are absent from Telab.

Here is the grammar used below. A hatted level or argument may be omitted; h ranges over the finite Timpl signature card, including its constructors and motive-annotated eliminators. e::=xUh[^]e^_(e:A)λϵ,ϱx.eeϵe(e,e)pr1(e)pr2(e),A::=x_U12NIdA(e,e)Vec[^](A,e)x:Aϵ,ϱAx:AA. The application marker ϵ is explicit or implicit. In a signature head, omission is permitted exactly at an external level or an implicit argument declared by that head; all motives remain written. A core preterm is the Timpl grammar from convention 112.1, extended only by level metavariables and occurrences ?α[δ]. Thus the grammar does not hide a second class of untyped core nodes.

For the rules below, whnf(A) is the unique weak-head form returned by the normalization interface of convention 112.1. A premise whnf(A)=H is an algorithmic head test, not a new judgmental equality rule.

When metadata matters, write x:Aϵ,ϱB, λϵ,ϱ(x:A).b, and fϵ,ϱa for the three core nodes. The ordinary x:AB, λ(x:A).b, and fa notations abbreviate the explicit-runtime case. No analogous superscripts are attached to Σ, pairs, or projections.

The distinction between explicit and implicit arguments is syntactic. Write x:AB and fa for explicit binding and application, and write {x:A}B and f{a} for their implicit counterparts. In this abbreviation the implicit binder is erased, so these forms mean x:Aimp,erasedB and fimp,eraseda. An implicit runtime argument is written with the full metadata notation. Thus every abbreviated form still fixes both bits required by the core checker.

An unannotated abstraction illustrates the first limit. There is no synthesis derivation for Γλx.x? because the domain cannot be recovered from the term. Against an expected type NN, however, the product head determines the domain and codomain, and the body checks in Γ,x:N. A hole has the reverse behavior: _N has enough type information, but no term. The elaborator records the missing term as a scoped unknown rather than inventing a global placeholder.

Definition 112.3 — Contextual metavariables

A contextual metavariable declaration has the form ?α:[ΔA], where Δ=x1:A1,,xk:Ak is a well-formed telescope and ΔA type. In a context Γ, an occurrence has the form ?α[θ], where θ:ΓΔ is a well-typed simultaneous substitution. A definition ?α:=[Δ]a is legal exactly when Δa:A, and replaces every occurrence by a[θ]. In worked constraint traces only, when Δ=Γ, the bare notation ?α abbreviates the identity occurrence ?α[idΓ]; declarations and generation rules retain the substitution explicitly.

A metacontext M is a dependency-ordered list of declarations and definitions. The type and body of an entry may mention only entries to its left. A term metavariable never denotes an external universe level; a level metavariable ranges over level expressions and belongs to a separate finite context L.

The explicit telescope and substitution on a metavariable occurrence enforce the contextual modal discipline; the solver below uses only the finite renaming instances displayed in this definition.

Definition 112.4 — Typed meta-substitution and problem-relative generality

Let M and N be dependency-ordered metacontexts. A typed meta-substitution θ:MN assigns to every entry ?α:[ΔA] of M a term [Δ]a well typed at A after the earlier assignments, with free metavariables drawn from N. Its action is postfix: ?α[δ][θ] is a[δ][θ], and the action extends structurally to contexts, types, terms, and constraints.

If ρ:NP, define postfix composition by X[θ;ρ]X[θ][ρ],(θ;ρ)(?α):=θ(?α)[ρ]. For a finite problem P, write dom(P) for the metavariables present before solving. Solutions θ1 and θ2 are compared only on that domain. Write MoreGeneralP(θ1,θ2) when some well-typed ρ satisfies ?α[θ2]?α[θ1][ρ]for every ?αdom(P). Residual fresh metavariables are immaterial: two solutions are identified when a dependency-preserving bijective renaming of those fresh entries makes their actions judgmentally equal on dom(P). A most general solution is one related by MoreGeneralP to every solution, modulo that equivalence.

For the hole _N in context x:N, create ?α:[x:NN] and return ?α[x]. If the hole is inside a second binder y:2, its occurrence is ?α[x,y] only when the declaration telescope includes both variables. The rejected definition ?α:[x:NN]:=[x:N]y(y:Nx:N) fails the typing premise of definition 112.3. Recording only a global symbol ?α would lose precisely this check.

Definition 112.5 — Heterogeneous constraints and solutions

An object constraint is either a type equation ΓAB type or a heterogeneous typed term equation Γ(s:S)(t:T). A type equation requires judgmental equality of two already well-formed types; it does not require them to inhabit a common universe. A solution of a term equation must first make S and T judgmentally equal types and must then, after conversion to either type, make s and t judgmentally equal. We abbreviate the homogeneous case by Γst:S. Heterogeneous equations are necessary while dependent indices are still unknown: two constructor spines need not have a common type before their index constraint is solved.

A formation guard has the form ΓA˙U. It is a suspended, syntax-directed universe-membership task, not an equation, and is never sent to the unifier. After object substitution it is compiled into the exact level premises of the Timpl formation rules by definition 112.11. The component C stores an ordered equation list and an ordered formation-guard list; concatenation preserves both orders.

A level constraint is either a strict equality L or a formation inequality +k, where k is a meta-level natural number. A constraint state (L;M;C;U) consists of a level context, a metacontext, a finite constraint component C, and a finite list of level constraints.

A solution (υ;θ) assigns level expressions to the unknowns in L and well-typed contextual definitions to the unsolved entries of M. It solves the state when every equation in C becomes judgmental equality in Timpl, every formation guard compiles without a flexible-head obstruction, and every equality or inequality in U, including those emitted by guard compilation, is valid for all values of the external level parameters. The type-equality and term-equality obligations are both part of solving an object constraint. Once the unique equality-level substitution has been fixed and applied, object solutions are ordered by the problem-relative predicate MoreGeneralP of definition 112.4; equivalently, θ2 agrees on the original problem domain with θ1;ρ for a well-typed substitution ρ on the remaining object metavariables in that equality-substituted state. Residual bound-level assignments are not ordered by instantiation. Their order is pointwise: νν exactly when ν(q)ν(q) for every bound metavariable q and every valuation of the external parameters.

The occurs check forbids a metavariable in its own definition; the scope check requires a proposed body to use only its declaration telescope. The two checks are different. The equation ?α[x]suc(?α[x]):N passes the scope check but fails the occurs check: no finite acyclic definition for ?α results. The equation ?α[x]y:N with yΔ can be acyclic but fails the scope check. Both checks precede every assignment.

Exercise 112.1

★☆☆ In context x:N,y:2, let ?α:[x:NN] and ?β:[x:N,y:2N]. Decide which of ?α[x]x,?α[x]ind2(z.N;x,suc(x);y),?β[x,y]x may orient from left to right as a contextual definition. For each rejected orientation name the failed premise of definition 112.3.

Generating typed constraints

Constraint generation traverses surface syntax to produce a typed core preterm and equations; it follows the bidirectional division of definition 48.16. It does not solve equations while traversing syntax; the separation makes the soundness invariant visible.

Definition 112.6 — Generation judgments

The judgments L;M;Γea:AL;M;C;U,L;M;ΓeAaL;M;C;U,L;M;ΓAtypeAL;M;C;U. respectively synthesize a Timpl type and preterm, check against a supplied Timpl type, or elaborate a well-formed type without asserting that it inhabits one universe. The third mode is necessary because the strict hierarchy of definition 29.1 is not cumulative. The output contexts extend the input contexts, and the returned term, type, and constraints may mention only output declarations. Premises are read left to right: each premise receives the output contexts of its predecessor, and their constraint lists are concatenated in that order. The rules use one fixed fresh-name supply. We also use two auxiliary judgments: L;M;Γ(a:A)@qb:BL;M;C;U,L;M;Γh(a;Δh;R)@qb:BL;M;C;U. The first consumes an ordinary written application spine. The second walks the dependency-ordered argument telescope of a fixed signature head h; its input a is the already elaborated prefix. A written argument is q=eϵ. In a signature telescope, every binder additionally has a surface policy ω{infer,write}; all motive binders have policy write. List concatenation of independently generated constraints is written with commas and always follows premise order. In long rules only, the abbreviations Ξi:=Li;Mi;Γ,Ωi:=Li;Mi;Ci;Ui carry no hidden operation: the index on Ξi names the level and metacontexts at stage i, while the index on Ωi names that stage’s output package; an unindexed input in a rule is Ξ0. The sequential package Ω1Ω2:=L2;M2;(C1,C2);(U1,U2) is defined only when the second premise starts in Ξ1, and extends associatively to a finite sequence of threaded packages. Thus merely prints the state threading and ordered concatenation already required by the judgments. If g is a formation guard, write Ωg for the same package with g appended to the guard projection of its constraint component. This operation does not run a solver. The atomic, checked-hole, direction-changing, and lambda clauses are

x:AΓ
L;M;Γxx:AL;M;;
E-Syn-Var
c[]:A is a fully level-instantiated signature atom
L;M;Γc[]c[]:AL;M;;
E-Syn-Atom
?α freshM=M,?α:[ΓA]
L;M;Γ_A?α[idΓ]L;M;;
E-Chk-Hole
L;M;Γea:BL;M;C;U
L;M;ΓeAaL;M;(C,ΓAB type);U
E-Chk-Syn
whnf(A)=x:Bϵ,ϱCL;M;Γ,x:BeCbL;M;C;U
L;M;Γλϵ,ϱx.eAλϵ,ϱ(x:B).bL;M;C;U
E-Chk-Lam

Universe membership has its own checking clause:

p,q well-formed level expressionswhnf(A)=Uq
L;M;ΓUpAUpL;M;;(p+1q)
E-Chk-Univ

The displayed inequality is recorded, not solved during generation. It is the exact side condition of U-Hier.

Holes and annotations in synthesis mode, and holes in type mode, are governed by the following rules. These rules fix the declaration order of the fresh level and object metavariables.

?u fresh?αA,?α freshL=L,?uM=M,?αA:[ΓU?u],?α:[Γ?αA[idΓ]]
L;M;Γ_?α[idΓ]:?αA[idΓ]L;M;;
E-Syn-Hole
L;M;ΓAtypeAL1;M1;C1;U1L1;M1;ΓeAaL2;M2;C2;U2
L;M;Γ(e:A)a:AL2;M2;(C1,C2);(U1,U2)
E-Syn-Ann
?u fresh?αA freshL=L,?uM=M,?αA:[ΓU?u]
L;M;Γ_type?αA[idΓ]L;M;;
E-Ty-Hole

Type formation is a separate inductive judgment, not an implicit appeal to a maximum universe. In E-Ty-Vec, levelL(^)=(,L0) means is the written well-formed level and L0=L, or =?u is fresh and L0=L,?u.

L;M;Γea:TL;M;C;Uwhnf(T)=Uu
L;M;ΓetypeaL;M;C;U
E-Ty-El
p a well-formed level expression
L;M;ΓUptypeUpL;M;;
E-Ty-Univ
D{1,2,N}
L;M;ΓDtypeDL;M;;
E-Ty-Base
Ξ0AtypeAΩ1Ξ1e0Aa0Ω2Ξ2e1Aa1Ω3
Ξ0IdA(e0,e1)typeIdA(a0,a1)Ω1Ω2Ω3
E-Ty-Id
levelL(^)=(,L0)Ξ:=L0;M;ΓΞAtypeAΩ1Ξ1nNnΩ2
Ξ0Vec[^](A,n)typeVec(A,n)(Ω1Ω2)ΓA˙U
E-Ty-Vec

Thus the legal input Vec[0]((x:N)N,0) first elaborates its product element type by E-Ty-Pi; the resulting guard is then discharged by U-Pi. No term-synthesis rule for a product is required.

The binding type formers thread the domain output into the opened codomain.

L;M;ΓAtypeAL1;M1;C1;U1L1;M1;Γ,x:ABtypeBL2;M2;C2;U2
L;M;Γx:Aϵ,ϱBtypex:Aϵ,ϱBL2;M2;(C1,C2);(U1,U2)
E-Ty-Pi
L;M;ΓAtypeAL1;M1;C1;U1L1;M1;Γ,x:ABtypeBL2;M2;C2;U2
L;M;Γx:ABtypex:ABL2;M2;(C1,C2);(U1,U2)
E-Ty-Sigma

Type-mode rule selection is deterministic. Inspect the outer constructor in this priority order: hole, universe literal, nullary base, identity, vector, product, and Sigma. Rule E-Ty-El is the fallback only for an atom outside those seven syntactic classes whose synthesis exposes a universe. It is therefore never tried after a recognized type-former rule has failed, and no surface type expression selects two type-mode clauses.

Pairs and projections have the following exact clauses. The weak-head premises are tests; failure gives no derivation.

whnf(A)=x:BCL;M;Γe0Ba0L1;M1;C1;U1L1;M1;Γe1C[a0/x]a1L2;M2;C2;U2
L;M;Γ(e0,e1)A(a0,a1)L2;M2;(C1,C2);(U1,U2)
E-Chk-Pair
L;M;Γea:AL;M;C;Uwhnf(A)=x:BC
L;M;Γpr1(e)pr1(a):BL;M;C;U
E-Syn-Fst
L;M;Γea:AL;M;C;Uwhnf(A)=x:BC
L;M;Γpr2(e)pr2(a):C[pr1(a)/x]L;M;C;U
E-Syn-Snd

Ordinary application is the least relation generated by E-Syn-App, E-Spine-Done, E-Spine-Insert, and E-Spine-Consume. Rule priority is part of the definition: insertion precedes the explicit case, a written implicit argument precedes insertion, and E-Spine-Done applies only when the written spine is empty and the exposed head is not an implicit product.

Ξ0ea:AΩ1Ξ1(a:A)@qb:BΩ2
Ξ0eqb:BΩ1Ω2
E-Syn-App
q=whnf(A)x:Bimp,ϱC
L;M;Γ(a:A)@a:AL;M;;
E-Spine-Done
whnf(A)=x:Bimp,ϱCq= or its first marker is exp?α freshM1=M,?α:[ΓB]mα:=?α[idΓ]Ξ1(aimp,ϱmα:C[mα/x])@qb:DΩ2
Ξ0(a:A)@qb:DΩ2
E-Spine-Insert
whnf(A)=x:Bϵ,ϱCΞ0eBdΩ1Ξ1(aϵ,ϱd:C[d/x])@qb:DΩ2
Ξ0(a:A)@(eϵ,q)b:DΩ1Ω2
E-Spine-Consume

A flexible or rigid nonproduct head and an explicitness mismatch have no rule. Consequently this relation inserts one unique consecutive block of implicit arguments and never guesses a relevance bit.

Finally let a signature entry have level parameters u, result R, and dependency-ordered argument telescope ((xi:Bi)ϵi,ϱi,ωi)i=1n. Written levels are copied; omitted levels are replaced from left to right by fresh level metavariables. This deterministic operation is written levelsh(^;L)=(;L0). The signature-head and telescope rules are:

levelsh(^;L)=(;L0)Ξ:=L0;M;ΓΞh(h[];Δh[/u];R[/u])@qb:BΩ1
Ξ0h[^]qb:BΩ1
E-Syn-Head
Δh=q=
L;M;Γh(a;;R)@a:RL;M;;
E-Head-Done
Δh=(x:B)imp,ϱ,infer,Δq= or its first marker is exp?α freshM1=M,?α:[ΓB]mα:=?α[idΓ]Ξ1h(aimp,ϱmα;Δ[mα/x];R[mα/x])@qb:DΩ2
Ξ0h(a;Δh;R)@qb:DΩ2
E-Head-Infer
Δh=(x:B)ϵ,ϱ,ω,ΔΞ0eBdΩ1Ξ1h(aϵ,ϱd;Δ[d/x];R[d/x])@qb:DΩ2
Ξ0h(a;Δh;R)@(eϵ,q)b:DΩ1Ω2
E-Head-Write

There is no omission rule for a write binder. This is the exact reason an eliminator motive cannot be invented by E-Syn-Head.

Rule E-Chk-Syn emits first-class type equality, so it remains applicable to well-formed mixed-level products that inhabit no common strict universe. When a type equation itself compares Ur with Us, rigid decomposition emits the strict level equality rLs. Separate membership premises emit lower-bound edges through E-Chk-Univ. The type rules never invent a maximum universe: the optional level on a surface vector is a formation witness, while the returned Timpl family is Vec(A,n). Every premise receives both output contexts of its predecessor. Lambda, pair, projection, ordinary-spine, and signature-head rules likewise copy their displayed dependency and metadata; a failed head test or marker match has no derivation. In particular a flexible application head is outside this direct generation fragment until an annotation exposes a product with both metadata bits, and no signature rule invents a written motive.

This repeated insertion of consecutive implicit binders is implicit saturation; it stops at the first explicit binder and does not choose among alternative spine shapes.

For a declared head, E-Syn-Head instantiates external levels before the head telescope is traversed. Thus an omitted level of append or map is fixed before ordinary implicit saturation, whereas E-Syn-Atom applies only after every external level has already been written.

The displayed rules cover all and only the forms of definition 112.2. In particular, both binding clauses elaborate their codomains in the opened context Γ,x:A; this is part of the inductive definition rather than an extensibility convention.

Expected-type propagation is already doing mathematical work in E-Chk-Lam: it moves B into the context before the body is visited. The same operation fixes both components of a pair. For example, checking (_,refl(_)) against n:NIdN(n,n) creates ?α:[ΓN],?β:[ΓN] and the second component generates ?β?α:N. The expected Σ-type is what makes both holes scoped and typed.

Example 112.7 — A constraint ladder

Each line changes one feature. ?α[]Nassign a closed type;Vec(?α[],m)Vec(N,m)decompose a common rigid head;?α[x]xabstract the permitted variable;?α[x]Vec(?α[x],m)reject the cyclic assignment. The first line needs ordinary assignment, the second rigid decomposition, the third contextual abstraction, and the fourth the occurs check. These four operations determine the readable solver below.

Lemma 112.8 — Generation invariant

Suppose a generation judgment starts from well-formed L, M, and Γ. Its output contexts extend the inputs and remain well formed. Both sides of every emitted type equation are well-formed types. In every emitted Γ(s:S)(t:T), both displayed typing judgments and both type-formation judgments hold under the output metacontext. Every emitted formation guard has a well-formed guarded type and level expression. Every emitted strict level equality and level inequality compares well-formed level expressions. Every returned preterm has the returned or expected type, conditional on the equation and formation-guard obligations in those constraints; every result of the third judgment is a well-formed type conditional on its formation guards.

Proof of Lemma 112.8 — Generation invariant

Proof. Use simultaneous induction on synthesis, checking, application-spine, and type-formation derivations. The variable, constant, and annotation cases apply their Timpl typing rules and the context-extension lemma. In E-Chk-Lam, inversion gives the domain B and codomain C; the induction hypothesis types b:C in Γ,x:B, hence the core abstraction has type A after the recorded head equality. Inversion also recovers the product’s explicitness and relevance; the rule requires the surface abstraction to agree and copies the same pair to the core abstraction. Pair checking uses the first induction hypothesis before substituting its returned term into the second component type. The substitution lemma therefore gives a well-formed second query.

For application, each inserted metavariable is declared at the exposed domain before its occurrence. Substitution gives C[?α/x] as the type of the partially applied core term. The explicit argument case then applies Π-elimination with the exposed binder’s two metadata bits. A flexible head produces no ill-typed preterm: generation reports the run outside the direct fragment until an annotation exposes a product. A hole is well typed by its declaration. The signature-headed schema follows by induction over its dependency-ordered telescope: after each argument, substitution types every later domain and the result. Thus it covers the constructor and eliminator cases, and a motive is an input rather than an untyped invention. In the binding-former case, the two type-formation induction hypotheses form A and B in succession, with B formed in Γ,x:A. The ordinary Π- or Σ-formation rule gives typehood without a universe-membership conclusion. The former copies the written explicitness and relevance, whereas the latter introduces no metadata. Rule E-Chk-Univ records a well-formed inequality, and rigid universe comparison records a well-formed strict equality. The induction hypotheses preserve both output contexts and type every constraint emitted by a surface type hole. ◻

Exercise 112.2

★★☆ Trace checking (0,refl(0)) against n:NIdN(n,0). Display the expected type of the second component after substitution. Then replace the first component by suc(0) and display the rigid identity-endpoint constraint that causes rejection.

Universe constraints

Term metavariables cannot solve a universe inequality. The elaborator uses the level-expression algebra of section 74.4 and solves a separate graph problem. The inequalities generated here are precisely those of U-Hier and the nullary closure rules; U-Cumul is absent from Timpl. Equality must first be decidable in that algebra.

Definition 112.9 — Canonical level expressions

Fix the declaration order of the external level parameters. A level atom is either a numeral 0+k or an expression p+k, where p is an external parameter and kN. An atom dominates another atom under all natural-number valuations precisely in one of the following cases:

  1. they have the same external parameter and the first offset is at least the second;

  2. both are numerals and the first numeral is at least the second; or

  3. the first is p+k, the second is 0+j, and kj.

The canonical level normal form lnf(e) is the declaration-ordered maximum of atoms obtained by distributing successor over maximum, retaining only the largest offset for each external parameter and deleting every dominated numeral. If no external atom dominates the largest numeral, retain that numeral as the first atom. Repeated atoms and the empty maximum are identified with one copy and 0, respectively.

For example, lnf(max(max(u,v)+1,u+3,2))=max(u+3,v+1). The numeral disappears because u+3 is at least 3 under every valuation. By contrast, the numeral in max(u,v,1) remains: the valuation u=v=0 makes it decisive.

Lemma 112.10 — Exact level normalization

For all level expressions e and e, normalization preserves their value under every natural-number valuation of the external parameters. Moreover, e and e have the same value under every such valuation if and only if lnf(e) and lnf(e) are syntactically identical.

Proof of Lemma 112.10 — Exact level normalization

Proof. Induction on e proves preservation. The zero case gives the atom 0+0. Successor adds one to every atom because max(a,b)+1=max(a+1,b+1). Maximum takes the union of the two atom lists. In each case, deleting a dominated atom preserves the maximum by the three clauses of definition 112.9.

It remains to prove uniqueness. In an irredundant list, the offset attached to an external parameter p is recovered by setting every other parameter to zero and letting the value of p exceed every displayed offset. Thus equal functions have the same external atoms and offsets. After those offsets are fixed, evaluating all parameters at zero recovers the retained numeral: when present it is strictly larger than every external offset, and when absent it was dominated by one of them. Declaration order then makes the two canonical lists syntactically identical. The reverse implication follows from the preservation calculation. ◻

Definition 112.11 — Formation-guard compilation

After applying every object assignment stored in M, normalize the guarded type to weak-head form and compile ΓA˙U by the following exhaustive clauses for the Timpl card: formΓ(Up,)={p+1},formΓ(D,)={0}(D{1,2,N}),formΓ(x:Bϵ,ϱC,)=formΓ(B,)++formΓ,x:B(C,),formΓ(x:BC,)=formΓ(B,)++formΓ,x:B(C,),formΓ(IdB(a,b),)=formΓ(B,),formΓ(Vec(B,n),)=formΓ(B,). If the weak-head form is a rigid neutral (N) and synthesis gives ΓN:Uq, emit the strict equality Lq. A still-flexible head returns outside; the compiler never guesses its universe. The base clauses deliberately emit 0, although that inequality is extensionally automatic: when is a fresh omitted vector level, it classifies as a bound metavariable and gives the least choice (0). These clauses are precisely U-Hier, U-Pi, U-Sig, the identity and vector closure rules, and the three base closure rules. Guard compilation therefore emits no object equation and no universe maximum.

Definition 112.12 — Stratified level problems

A stratified level problem partitions its level metavariables into equality metavariables and bound metavariables by the following deterministic collection policy. A fresh level metavariable starts unclassified. The first strict equality that orients it to an occurs-free expression classifies it as an equality metavariable; an equality between two unclassified metavariables orients the later declaration to the earlier one. After all strict equalities have been collected and substituted, an unclassified metavariable occurring as the right endpoint of a formation inequality becomes a bound metavariable. Any still-unclassified metavariable is ambiguous, and any strict equality still mentioning a bound metavariable is outside this stratified grammar. Thus classification is generated from constraint roles, not supplied as unexplained input data. Each equality metavariable q has at most one direct assignment qLe, where e is occurs-free and is built from zero, external parameters, and earlier equality metavariables by successor and maximum. Equality assignments are processed in declaration order and substituted through the rest of the problem. No equality metavariable may remain afterward. Normalize a residual rigid equality with lnf; such an equality contains only zero and external parameters. Delete it when the normal forms are identical and reject it otherwise. An equality that still mentions a bound metavariable is outside the stratified grammar.

Before constructing the residual bound graph, normalize every inequality whose right side contains no bound metavariable. Such an inequality is valid for all external-parameter valuations exactly when every atom of the left normal form is dominated, in the sense of definition 112.9, by some atom of the right normal form. Delete a valid rigid inequality and reject an invalid one. The residual bound part is then a finite set of inequalities p+kq, where p is an external parameter, bound metavariable, or zero; q is a bound metavariable; and kN. The two metavariable classes are disjoint. Comparing strict universes Ur and Us generates a level equality; if it orients toward a fresh equality metavariable, it must fit (112.5). Separately, E-Chk-Univ and formation-guard compilation generate p+1q when Up is checked against Uq. Replace max(p1,,pr)+kq by its r component inequalities. After the rigid discharge, the upper normal form must be one bound metavariable q. An upper maximum containing a bound metavariable is disjunctive rather than a difference-constraint edge and is reported outside this stratified fragment; an upper maximum containing no bound metavariable was already decided by the atomwise test.

Regard (112.6) as an edge pkq. Adjoin a zero-weight edge 00q for every bound metavariable q; this records the implicit natural-number lower bound and does not change the set of solutions. Compute strongly connected components of the full nonnegative-weight graph. Reject any component containing a positive-weight edge: within a strongly connected component that edge lies on a positive cycle. Every remaining component has only zero-weight edges; collapse those components. On the resulting acyclic graph, assign to each unknown q the maximum of p+k over all paths from zero or an external parameter p to q.

The constraints u+1r and v+1r give r=max(u,v)+1. The constraints r+1s and s+1r form a positive cycle and are rejected. Weak cycles merely identify levels.

Theorem 112.13 — Canonical stratified level solution

The algorithm of definition 112.12 terminates. It rejects exactly the unsatisfiable stratified level problems, and otherwise returns the unique normalized equality assignments followed by the pointwise least solution of the residual bound problem.

Proof of Theorem 112.13 — Canonical stratified level solution

Proof. The dependency-ordered equality pass terminates, and its grammar makes each assignment unique after normalization. By lemma 112.10, two residual rigid normal forms are identical exactly when their equality is valid under every valuation; when they differ, the separating valuation from that lemma proves the rejection sound and complete. An occurs check or a second, incompatible direct assignment is outside the stratified grammar rather than a solver branch. Substitution leaves a finite collection of bounds. For a rigid upper bound, atomwise domination is equivalent to universal validity of one maximum below another: each left atom must be bounded by a right atom, and the three domination clauses prove sufficiency; a failing atom supplies a separating valuation. The discharge pass is therefore sound and complete. What remains is a finite nonnegative-weight bound graph.

Compute its full strongly connected components. Such a component contains a positive edge exactly when it contains a positive cycle; summing that cycle’s inequalities yields q+kq for k>0, which has no natural-number solution. Conversely, if no component contains a positive edge, every internal edge has weight zero. After those components are collapsed, define the value at a vertex by the maximum weight of every path ending there, with zero or the path’s external parameter as base. The adjoined zero edge ensures that this set is nonempty for every bound vertex. A finite acyclic graph has finitely many paths. Appending an edge pkq shows that the assigned value of q is at least the assigned value of p plus k, so every constraint holds.

Let ν be any other solution. Induction along a path gives p+kν(q) for the path’s accumulated weight k. Taking the maximum over all such paths shows that the constructed value is at most ν(q). Hence it is the pointwise least solution. ◻

Exercise 112.3

★★☆ Solve u+1r,vr,r+1s,v+3s. Give the least expressions for r and s. Add s+1r and display the positive cycle certificate.

Weak-head simplification

Syntactic decomposition before computation is unsound. The two types (λx.Vec(A,x))mandVec(A,m) have different raw heads and the same weak-head form. Conversely, unfolding every subterm to full normal form spends work in components that a head comparison may never inspect.

Definition 112.14 — Rigid and flexible weak heads

Weak-head normalization reduces head β-redexes and the computation rule of an eliminator whose scrutinee has constructor head. A weak head is flexible when the head of its neutral spine is an unsolved metavariable, even when applications or stuck eliminators follow that head. It is rigid when the spine head is a bound variable, declared constant, type former, or constructor, or when an eliminator is stuck on such a rigid neutral. Thus ?α[x]y is flexible for classification, although it will be outside the direct fragment below.

Before classifying heads, delete any normalized heterogeneous constraint whose two types and whose two terms are respectively judgmentally identical. A remaining constraint is flex–rigid when exactly one term head is flexible, flex–flex when both are flexible, and rigid–rigid otherwise. The types are simplified before the terms; the terms are normalized only far enough to make this classification.

Definition 112.15 — Rigid simplification

After weak-head normalization, simplify a heterogeneous rigid–rigid equation as follows.

  1. First simplify the equation between its two types. Reject a rigid type clash. Once the types convert, regard the term equation as homogeneous.

  2. Delete every normalized reflexive equation, irrespective of whether its common head is rigid or flexible.

  3. Decompose two occurrences of the same type former or constructor into equations between corresponding arguments. Dependent spine arguments are processed from left to right, so each earlier equality converts the types of the later pair.

  4. Compare two abstractions by extending the context with one variable and comparing their bodies. The normalization interface supplies eta-long forms, so a neutral function at product type is exposed as an abstraction before this clause is used. It also canonicalizes every Unit-typed term to and exposes a Sigma-typed neutral as a pair before component comparison.

  5. Comparing Ur with Us emits the strict level equality rLs. Before any suspended term equation is exposed, run the equality stratum of definition 112.12: orient a permitted equality metavariable, substitute its normalized assignment through the entire combined state, and delete a reflexive rigid equality or reject a distinct one. Separately, E-Chk-Univ emits p+1q when checking Up against Uq.

  6. Reject distinct rigid heads, including distinct constructors of 2, N, or Vec.

  7. Leave an equation stuck only when at least one side has a flexible head.

The fresh variable in item 4 avoids the free variables of both sides and of the constraint context. For a first-class type equation, skip item 1 and apply items 2–7 directly to the two well-formed type expressions. For a heterogeneous term equation, item 1 is a separate type-equation task and must finish before term-head classification.

Lemma 112.16 — Rigid simplification preserves solutions

Each step of definition 112.15, including an update of the level state, preserves and reflects the combined solution pairs of its input state. A rigid type- or term-head rejection has no solution.

Proof of Lemma 112.16 — Rigid simplification preserves solutions

Proof. Weak-head normalization preserves judgmental equality. Solving the type obligation licenses context conversion to a homogeneous term equation. Congruence proves that solutions of the component equations solve the original equation. Constructor injectivity supplied by the Timpl conversion interface gives the converse; dependent spines use context conversion after each earlier component. Function extensionality is not used: eta-long normalization exposes both functions as abstractions, after which the abstraction clause compares their bodies under the same fresh variable. At 1, both normal forms are , so the equation is reflexive. At a dependent Σ-type, eta-long normalization exposes both terms as pairs; injectivity first compares their projections and then compares the second components after the first-component conversion. Applying these three clauses recursively is why variables of contractible nested Unit/Sigma type do not create additional rigid solutions. Disjoint normal rigid heads cannot be judgmentally equal by constructor inversion.

For the universe clause, a combined solution of rLs makes the two level expressions equal under every external-parameter valuation. Orienting an allowed equation qLe and substituting e for q preserves and reflects combined solutions by the substitution property. If neither side is orientable, lemma 112.10 shows that identical normal forms are valid under every valuation and that distinct normal forms have a separating valuation. Thus deletion and rejection preserve exactly the old solution set. The formation inequality emitted by E-Chk-Univ is a generation constraint, so this simplification step merely retains it in the level state. ◻

Exercise 112.4

★★☆ Let Γ0=A:Uu,m:N,a:A,ys:Vec(A,m),?p:[Γ0N], and extend Γ0 by xs:Vec(A,?p[idΓ0]). Write π for the weakening projection from that extended context to Γ0. Decompose the heterogeneous constraint (vcons(?p[π],a,xs):Vec(A,suc(?p[π])))(vcons(m,a,ys):Vec(A,suc(m))). Write the outer type and index equations first, solve ?p, and state the context conversion needed before comparing the tails. Explain why comparing the tails before solving the index would not give a well-typed homogeneous equation.

The higher-order pattern boundary

A higher-order pattern occurrence is a metavariable applied to a list of pairwise distinct bound variables. The contextual occurrences below are this chapter’s telescope-typed form of that restriction.

The equation ?α[x]suc(x) determines a function. A non-pattern observation need not even have a most general unifier. Fix the simply typed signature containing one base type o, one constant c:o, and no eliminators, and let ?F:[x:oo]. The equation ?F[c]c:o has the two solutions ?F:=[x]x and ?F:=[x]c. They are incomparable: an instance of the first still maps a fresh variable to that variable, while an instance of the second maps it to c. Moreover they have no common more-general unifier. Indeed, put the body of any proposed unifier into beta-normal, eta-long form. In the context x:o, substitution of c can produce the rigid canonical form c without a residual equation only when that body is x or c; a neutral headed by a residual metavariable stays neutral. Thus every unifier is one of the two displayed classes.

This proves non-unitarity of a typed non-pattern problem; the existence of several solutions alone would not. The stronger undecidability boundary for unrestricted higher-order unification and the unitary restricted result for exact CoC patterns do not transfer to the larger elaborator of this chapter. Our direct fragment therefore requires every flexible argument list to exhibit the variables on which the unknown may depend.

Definition 112.17 — Direct contextual-pattern fragment

An occurrence is a contextual pattern occurrence when it has the form ?α[x1,,xk], the xi are pairwise distinct, and the displayed substitution is a well-typed variable renaming from the declaration telescope of ?α. A state is in the direct contextual-pattern fragment when weak-head simplification exposes only such occurrences as an entire flexible side and the following pruning-free conditions hold at every state reached by the fixed strategy. In particular, a metavariable occurrence followed by an application or stuck eliminator is outside this fragment even though its neutral head is flexible for classification. The conditions are:

  1. in every flex–rigid constraint ?α[x]t, every occurrence of ?α and every occurrence of a free ordinary variable outside x is rigid in the sense defined below, while every other metavariable of t can be moved before ?α by a dependency-preserving permutation;

  2. every flex–flex restriction has a well-formed dependency-closed common telescope and result type;

  3. substituting a candidate assignment and weak-head simplifying does not expose a non-pattern occurrence; and

  4. after the equality-level substitution, every candidate object body checks at its declared result type without using a residual formation bound or instantiating a bound-level metavariable.

The test is performed before committing each transition. Its possible outcomes are therefore inside, outside the direct fragment, and unsatisfiable. Outside is not a proof of unsatisfiability. The solver does not postpone, prune, imitate, project, or search.

An occurrence inside a normal term is rigid when the path from the term root to that occurrence passes through no subterm with a flexible head; the occurrence’s own head is not counted. A forbidden variable or self-occurrence below another flexible head may be removed by pruning and is therefore outside this direct fragment. The same occurrence below only rigid constructors cannot be repaired by instantiating another metavariable and is eligible for a scope or occurs certificate.

For example, in x,y:N, ?α[x]suc(?β[y]) is a contextual-pattern equation but is outside the direct fragment. A pruning solver could introduce ?γ[], set ?β:=[y]?γ[], and then solve ?α. The direct solver reports outside; it does not call the solvable state a scope error. This distinction is the price of the short completeness proof.

Definition 112.18 — Flex–rigid assignment

Consider Γ?α[x1,,xk]t:A. Orient the flexible side to the left. Assign ?α:=[z1:A1,,zk:Ak]tnf[z1/x1,,zk/xk] exactly when:

  1. ?α does not occur in tnf;

  2. every free ordinary variable of tnf is among the xi;

  3. every metavariable in tnf precedes ?α, after a dependency-preserving permutation of independent declarations; and

  4. after applying the equality-level substitution, the candidate body checks against the declared result type of ?α without appealing to a residual formation bound or assigning a bound-level metavariable.

Before applying items 1–3, compute the beta-iota normal, eta-long form tnf supplied by convention 112.1, and use that normal form in both the tests and the displayed assignment. This canonical-form precondition is essential: a variable hidden in a discarded beta argument is not a scope occurrence, and a self-occurrence hidden there is not a cycle. Canonical forms therefore determine the scope and cycle tests rather than merely optimizing them. After assignment, substitute the definition through the remaining state. If item 2 fails only because an out-of-scope variable occurs below another flexible head, report outside the direct fragment; pruning could still produce a solution. A rigid out-of-scope occurrence is an actual scope failure. Failure of item 4 solely because universe membership awaits a residual bound is outside, not unsatisfiable. For example, ?A:[ΓUq]Up is deferred by this finite policy when only p+1q could license the assignment; the chapter does not claim a principal object substitution before that bound is instantiated.

For example, ?α[x,y]vcons(0,x,?β[y]) orients only if x:A, y:B, ?β precedes ?α, and the constructor has the declared result type. The assignment abstracts both variables even though the body ignores no declared dependency. In contrast, ?α[x]y fails item 2 and ?α[x]suc(?α[x]) fails item 1.

Lemma 112.19 — Flex–rigid most generality

When the four premises of definition 112.18 hold in the direct fragment, the assignment in (112.9) is a most general solution of (112.8). If item 1 or item 2 fails by a rigid occurrence, the equation has no finite well-scoped contextual solution.

Proof of Lemma 112.19 — Flex–rigid most generality

Proof. Substitution into the abstraction yields tnft. The assignment is therefore a solution. Let θ be any other solution. Since the argument list is a bijective renaming of the declaration telescope, abstracting the equality θ(?α[x1,,xk])θ(t) gives an equality of contextual definitions. Define b:=tnf[z1/x1,,zk/xk]. Then θ(?α)=[z1:A1,,zk:Ak]θ(b). Thus θ factors through the displayed assignment on ?α; it may still instantiate the metavariables of tnf, which is exactly the remaining freedom. A rigid self-occurrence survives every substitution and would make a finite term contain itself as a proper subterm. A rigid variable outside the telescope survives substitution but is not in scope in any legal definition of ?α. ◻

Definition 112.20 — Flex–flex intersection and insertion

For an equation ?α[x1,,xk]?α[y1,,yk], retain exactly those telescope positions i for which xi=yi, together with every earlier position on which the retained variables’ types and the result type depend. If dependency closure would retain a position with xiyi, report the state outside the direct fragment. Otherwise create ?β:[ΔA] and define both sides through ?α:=[Δ]?β[πΔ]. This rule is reached only after the heterogeneous type task has been solved. Consequently, if a result type itself mentions a mismatched actual parameter, its rigid type equation fails as unsatisfiable before flex–flex intersection. The outside outcome above concerns a dependency-closure failure that remains after the two occurrence types have converted. For distinct metavariables, retain the ordinary variables that occur in both argument lists, ordered as in the ambient context, and close that list under dependencies. Define each metavariable through one fresh ?β over the retained telescope, provided both declaration telescopes admit the required projections and the two result types are judgmentally equal after restriction. The fixed left-to-right order chooses the fresh name; it does not choose a value for it.

The metacontext operation is part of the rule. First take a dependency-preserving topological permutation that places all declarations needed by Δ and A before the target declaration or declarations. Insert ?β immediately before the earliest target, replace each target declaration by the displayed definition through ?β, and substitute those definitions through every later declaration, definition, and constraint. Recheck the resulting suffix. If a target is a prerequisite of the fresh declaration, or if two targets cannot be brought to this position without reversing a dependency, the state is outside the direct fragment.

Thus ?α[x,y]?α[z,y], for pairwise distinct variables x,y,z, forces the result to ignore the first formal parameter and preserves dependence on the second. The equation ?α[x,y]?α[x,z] preserves the first formal parameter instead. A result type mentioning a discarded parameter prevents any restriction that would discard that parameter.

Lemma 112.21 — Contextual factorization

Let Δb:A be beta-iota normal and eta-long, and let σ,τ:ΓΔ be variable renamings. If b[σ]b[τ], then σ(z)=τ(z) for every zFV(b).

Proof of Lemma 112.21 — Contextual factorization

Proof. Induct on the normal form of b. The variable case is immediate when its type has no uniqueness rule. At Unit type the canonical form is , so the free-variable set is empty. At Sigma type eta-longness exposes a pair and the introduction argument below applies componentwise. An introduction applies the induction hypothesis to each normal component. A neutral has a rigid variable or constant head: rigid-head injectivity first identifies the heads and then identifies corresponding spine arguments, to which the induction hypotheses apply. Eta-longness covers function type without an extensionality principle. Recursive Unit normalization also removes a variable hidden in a contractible Sigma component. These cases exhaust normal Timpl terms under the conversion interface of convention 112.1. ◻

Lemma 112.22 — Common-support factorization

Let Δαb:Aα and Δβc:Aβ be normal and eta-long. Suppose injective variable renamings from direct-pattern spines σ:ΓΔα and τ:ΓΔβ satisfy b[σ]c[τ]. If Δ is the dependency-closed telescope of ordinary variables occurring in both renaming images, and the result types agree after restriction, then there is a normal w over Δ such that bw[πα],cw[πβ], where πα,πβ are the dependency-preserving projections from the two declaration telescopes.

Proof of Lemma 112.22 — Common-support factorization

Proof. Normalize the common instance to n. Since substitution by a variable renaming preserves normality and free variables, FV(n)=σ(FV(b))=τ(FV(c))im(σ)im(τ). Replace those common images by the corresponding variables of Δ; the resulting normal form is w. Injectivity of each pattern renaming and induction on normal forms give bw[πα] and cw[πβ]. Dependency closure types every replacement, and the restricted result-type equality types the common residual body. This is the two-body form of lemma 112.21; it uses no choice of a value for the residual body. ◻

Lemma 112.23 — Flex–flex most generality

When the dependency-closure and metacontext-insertion tests succeed, (112.10) is a most general solution of the flex–flex equation. Every solution in the direct contextual-pattern fragment is independent of a mismatched position.

Proof of Lemma 112.23 — Flex–flex most generality

Proof. The two instantiated occurrences beta-reduce to the same application of ?β, so the construction is a solution. For a self-equation, any solution supplies one normal body. Applying lemma 112.21 successively shows that body is independent of every mismatched position, so it factors through the projection to Δ.

For distinct targets, let a solution assign normal bodies bα and bβ. Their instances have a common normal form because the solution satisfies the equation. By lemma 112.22, both bodies factor through one residual body w over the dependency-closed intersection telescope. Instantiating the fresh ?β by w therefore factors the arbitrary solution through the displayed pair of definitions. This proves most-generality for distinct as well as repeated metavariables. Dependency closure is necessary because removing a variable while retaining a type that mentions it would not form a telescope or a result type. The topological permutation preserves the earlier-than relation for every dependency edge. Weakening types ?β at its insertion point; replacing the targets and applying typed substitution to the suffix preserves the metacontext invariant. ◻

Theorem 112.24 — Terminating pattern simplification

Let (L;M;C;U) be a finite, well-formed constraint state whose equation projection lies in the direct contextual-pattern fragment and whose initial and simplification-emitted level constraints form one stratified level problem. Formation guards are carried unchanged and are compiled after object substitution; their emitted level constraints join the same stratified problem. On the equation projection, the fixed object strategy weak-head simplification and reflexive deletion, then rigid decomposition,immediate level-equality orientation and substitution whenever emitted,then flex--rigid assignment, then flex--flex intersection. terminates. It returns an object-unsatisfiability certificate, the outcome outside, or the unique normalized equality-level substitution υ=, a most general object substitution θ well typed in the υ=-substituted state, and an accumulated residual bound problem B. Every successful step preserves solution pairs for the equation and level projection: if (ν,σ) solves that projection, then ν extends υ=, satisfies B, and ?α[σ]?α[θ][ρ] for every input metavariable, for some well-typed substitution ρ on the remaining object metavariables; conversely every such ν and ρ solves that projection. Each rejection from the object or equality-level pass certifies that its projection has no solution. The residual bound solver and final formation-guard compilation remain. Inputs or intermediate states that fail a direct-fragment test receive the distinct outcome outside, for which the theorem makes no completeness claim.

Proof of Theorem 112.24 — Terminating pattern simplification

Proof. Normalize only for the proof measure, and order states lexicographically by:

  1. the number of unsolved equality-level metavariables;

  2. the number of unsolved object metavariables;

  3. the sum of the declaration-telescope lengths of unsolved object metavariables;

  4. the total erased-subject size of the normalized equality tasks; and

  5. the number of constraints.

Measure solver checkpoints immediately after weak-head simplification, but measure equality subjects by the size of their total normal forms. A heterogeneous constraint is counted as its active type-equality task together with its suspended term-equality task. Erase the ambient type annotation of each task and any declaration-signature material recovered by a head lookup. Thus comparing cx with cy counts the two applications, while the component comparison counts x and y, not the possibly larger declared domain written beside them. This proof measure exists by the hypothesis in convention 112.1. The operational solver computes only weak-head forms for rigid classification, but computes a full canonical form immediately before a flex–rigid occurs, scope, or assignment test, as required by definition 112.18. Before head classification, normalized reflexive deletion removes constraints such as ?α[x]?α[x]. A flex–rigid assignment decreases the second component. A flex–flex intersection replaces one or two unknowns by one unknown over a proper smaller telescope, decreasing the second component or, for a self-equation, the third. Solving the type task of a heterogeneous constraint deletes that already-counted task and exposes its already-counted suspended term task. Every rigid decomposition replaces a normal constructor, type former, abstraction, or rigid neutral spine by proper normalized subject subexpressions and introduces only erased ambient annotations; it therefore decreases the fourth component. Deletion decreases the fourth or fifth component. An oriented universe equality decreases the first component before its substitution can enlarge a later task; a normalized rigid equality is deleted or rejected. Only after this pass does the suspended term task become active. The strategy forbids a step that leaves the state unchanged, so there is no infinite run.

Every step preserves the combined solution pairs and object most-generality by lemma 112.16, lemma 112.19, lemma 112.23. A terminal nonempty state cannot contain a rigid–rigid equation, because decomposition or rejection would apply. It cannot contain a flex–rigid or flex–flex pattern equation, because the corresponding assignment or a justified occurs or rigid scope failure would apply. Hence a nonfailed terminal state has no equations and its accumulated substitution is most general in the equality-substituted state. For example, U?Uu first assigns ?:=u throughout the state, making a subsequent object assignment at Uu genuinely well typed; U0U1 is rejected before any suspended term task is exposed. The bound phase of theorem 112.13 subsequently accepts or rejects B. Conversely each object rejection clause identifies a rigid-head clash, cyclic finite term, or rigid scope escape, none of which a direct contextual-pattern solution can repair. Every pruning, non-pattern, or metacontext-ordering failure was separated earlier as outside and is not used in this converse. ◻

Exercise 112.5

★☆☆ Solve ?α[x,y](x,suc(x)):n:NN, where ?α:[x:N,y:2n:NN]. Write the contextual abstraction and verify its type. State why the unused argument y does not violate the pattern condition.

Exercise 112.6

★★☆ Let ?α:[x:N,y:NN]. Compute the most general solutions of ?α[x,y]?α[x,z]and?α[x,y]?α[z,y]. Here x,y,z:N are pairwise distinct. For each solution give the retained telescope. Then change the declared result type to Vec(N,y). Identify which equation the preliminary type task rejects, give the solver’s three-valued outcome, and say which intersection is still reached.

Exercise 112.7

★★☆ For the one-base-type signature of (112.7), prove that [x]x and [x]c are incomparable unifiers and that no third unifier is more general than both. Then explain exactly why the flex–rigid proof of lemma 112.19 is unavailable.

Elaborating vector append

Return to (112.1). The declaration is externally polymorphic in one level and implicitly polymorphic in its element type and indices: append:[u]{A:Uu}{m:N}{n:N}Vec(A,m)Vec(A,n)Vec(A,n+m). The body is the vector eliminator term constructed in construction 78.5; the declaration contains no surface pattern clauses. The type-formation judgment establishes that the displayed product is a type; it does not assign that mixed-level product to an invented maximum universe.

Synthesis of append returns (112.11). Before the written argument xs, implicit saturation creates ?,?X:[ΓappU?],?p:[ΓappN],?q:[ΓappN] and the core spine append[?]{?X}{?p}{?q}. Checking xs against Vec(?X,?p) emits Vec(?X,?p)Vec(A,m), whose rigid decomposition gives the heterogeneous element equation (?X:U?)(A:Uu)and?pm:N. The type obligation of the element equation is U?Uu. Its universe-head comparison emits ?Lu, whose normalized assignment is ?=u. Checking ys then emits Vec(A,?q)Vec(A,n), so ?qn. Substitution produces exactly append[u]{A}{m}{n}xsys:Vec(A,n+m). Every unknown is fixed by a typed equation. No search branch and no constructor clause is involved.

An expected result can propagate information in the other direction. In the context A:Uu,m:N,n:N,xs:Vec(A,m), checking appendxs_ against Vec(A,n+m) fixes the second hole at Vec(A,n). Without the expected result, the hole still has a contextual type after the first argument, but its index metavariable remains unsolved until another constraint mentions it.

Soundness and the exact completeness claim

A solver may stop with constraints or with unsolved metavariables. Neither state is a successful elaboration.

Definition 112.25 — Successful elaboration

A generation run is solved when:

  1. it starts in a metavariable-free object context, every generated object equation lies in the direct contextual-pattern fragment and the solver returns a well-typed substitution;

  2. after object substitution, every formation guard compiles without a flexible-head obstruction, and every universe constraint generated initially, emitted while simplifying object constraints, or emitted by guard compilation belongs to one stratified level problem; its equality stratum is solved and substituted before the bound solver returns a solution of the accumulated residue; and

  3. applying both solutions leaves no metavariable in the returned context, type, or term.

Before exposing a solved result, an implementation also submits the completed annotation certificate defined below to the independent rechecker. Kernel rejection is an implementation failure, not an additional constraint-solver condition.

Theorem 112.26 — Constraint-generation soundness

Let a synthesis or checking generation judgment return the core preterm a at synthesized or supplied type A, satisfy the hypotheses of lemma 112.8, and let (υ;θ) solve its generated constraints. Then Γ[υ][θ]a[υ][θ]:A[υ][θ]. For the third generation judgment, the corresponding conclusion is Γ[υ][θ]A[υ][θ] type.

Proof of Theorem 112.26 — Constraint-generation soundness

Proof. Apply (υ;θ) to the simultaneous induction proving lemma 112.8. Each conditional equation becomes a Timpl judgmental equality, so conversion discharges it. The application case deserves inspection. An inserted argument has its exposed domain by the contextual declaration, and substitution gives the instantiated codomain; Π-elimination therefore types the extended spine. An explicit argument is typed by the checking induction hypothesis. Repeating these two steps types the whole application.

In the expected-lambda case, weak-head inversion gives Ax:Bϵ,ϱC. The induction hypothesis types the body at C, Π-introduction types the abstraction at the product, and conversion gives type A. Pair, constructor, vector-eliminator, and identity-eliminator cases apply their displayed Timpl rules. Universe solutions instantiate only rule indices, and theorem 112.13 shows that every required strict equality and formation inequality holds. The type-formation cases apply the fixed Timpl formation rules directly after their generated constraints are solved. In E-Ty-Vec, the validated formation guard is exactly the element-universe premise of Vec-form; it may have been produced by recursively elaborating a binding type former. ◻

Definition 112.27 — The independent Timpl certificate rechecker

Use exactly the three ordered recursive functions Rty,Rsyn,Rchk and their exhaustive clause table in definition 110.22. No extension is implicit: that table contains every recognized full-Timpl head. A type with no direct Rty head—in particular a strict-lift type—is emitted as an annotated universe element, then checked by Syn-Ann and decoded by Ty-El. A solved elaboration emits the table’s surface syntax with all holes replaced, every contextual metavariable instantiated, all external levels normalized, and every motive, parameter, index, explicitness bit, and relevance bit stored.

Certificate acceptance is therefore the exact algorithm of definition 110.22: recheck the stored surface certificate for the claimed type, run Rchk at that type, and compare the returned core term with the claim up to alpha-equivalence. Level equality is strict normalized equality; the only bounds checked inside this table are the strict premises printed in Chk-Code-Univ and Chk-Code-Lift. Every other elaboration-time formation guard must be discharged before the certificate is emitted. No clause inserts an argument, solves a metavariable, reconstructs a motive, or accepts by erasure.

Lemma 112.28 — Timpl certificate completion

From a metavariable-free derivation D:Γa:A, including its presupposed formation derivation DA:ΓA type, one can compute a fully annotated Timpl certificate. Namely, put τD:=annTy(DA) and eD:=ann(D); then (Γ,τD,eD,A,a) is accepted by the independent annotation rechecker of definition 112.27.

Proof of Lemma 112.28 — Timpl certificate completion

Proof. Translate DA and D to the economical structural presentation and induct simultaneously, defining annTy and ann in the same recursion. The following list is exhaustive and names the selected rechecker clause.

last Timpl rule fields stored by ann selected clause
variable; 1 introduction none Syn-Var; Syn-
2 introductions constructor head Syn-True; Syn-False
N introductions recursively annotated predecessor Syn-Zero; Syn-Suc
Π introduction; elimination (ϵ,ϱ,A,x.B) Chk-Lam; Syn-App
Σ introduction; eliminations A,x.B Chk-Pair; Syn-Fst; Syn-Snd
2 elimination scrutinee, k.C, two branches Syn-BoolInd
N elimination scrutinee, k.C, zero and step methods Syn-NatInd
identity introduction; elimination A,a,b and the full x,y,p.C motive Chk-Refl; Syn-J
universe code or strict lift normalized levels and all code arguments Chk-Code-1; Chk-Code-N; Chk-Code-2; Chk-Code-Univ; Chk-Code-Pi; Chk-Code-Sg; Chk-Code-Id; Chk-Code-Lift; Chk-Code-Vec
vector family; introductions i,A,n and constructor arguments Ty-Vec; Syn-VNil; Syn-VCons
vector elimination i,j,A,n.v.P,p0,ps,m,ys Syn-VecInd
conversion proper typing premise wrapped in its inferred-type annotation; claimed type Syn-Ann, then Chk-Conv

For each row, the induction hypotheses reconstruct every premise printed in the named clause; applying that clause returns the same core node and result type. In the conversion row, if the proper typing premise returns a:C, ann emits (eD:annTy(DC)). Rule Syn-Ann therefore synthesizes C even when eD has an introduction head, after which Chk-Conv compares C with the claimed type. The rechecker never falls through from a failed recognized introduction clause. The type-formation induction uses, respectively, Ty-Pi, Ty-Sg, Ty-Id, the three Ty base clauses, Ty-Vec, Ty-Univ, or Ty-El. Universe-code formation uses the corresponding one of the nine Chk-Code clauses. Strict normalized comparison checks all stored levels and formation bounds; unPiMeta checks both metadata bits. These cases exhaust the fixed Timpl rule card. Erasure of ann(D) is a, so the final alpha-comparison succeeds and the certificate is accepted. ◻

Corollary 112.29 — Elaboration soundness

If e has a solved elaboration a:A in Γ, then Γa:A is derivable in Timpl and its completed annotation certificate is accepted by the independent rechecker. Surface holes, implicit arguments, and level metavariables add nothing to the trusted core.

Proof of Corollary 112.29 — Elaboration soundness

Proof. Apply theorem 112.26 to the well-typed solutions returned by the two solvers. Because the input context is metavariable free and the solved result contains no metavariables, Γ[υ][θ]=Γ. Apply lemma 112.28 to the resulting derivation. The independent acceptance is therefore a computed consequence, not an appeal to the elaborator’s internal derivation object. ◻

Completeness requires a search policy, not merely a surface grammar.

Definition 112.30 — Ground-determination certificate

Let D contain the metavariables reachable from a generated state’s returned term and type after equality-level substitution. Write d:D{0,,|D|1} for a strict ranking. A ground-determination certificate is a strict ranking d such that, for every ?αD, after substituting the assignments of lower rank the state contains a direct flex–rigid equation ?α[x1,,xk]t:A whose right side contains only rigid syntax and lower-ranked metavariables, passes the occurs, scope, typing, and static-pattern tests, and therefore has the unique assignment [x1,,xk]t. The dependency slice used by the certificate contains no flex–flex equation and introduces no fresh metavariable; states that require intersection or pruning are outside this decidable policy. No member of D may be discharged by generalization. This finite certificate is checked from equations and ranks; it does not presuppose that the elaboration algorithm has succeeded. Here reachable means membership in the least set containing the object metavariables free in the returned term and type and closed under object metavariables in their declared types and bodies, in both sides and the type of every generated object equation, and in the guarded type of every formation guard.

Definition 112.31 — Policy-aligned generation runs

A generation run for a surface term is policy-aligned when:

  1. every introduction in synthesis position has an annotation;

  2. implicit saturation stops at the first explicit binder and never inserts an explicit argument;

  3. every generated object equation remains in the direct contextual-pattern fragment after substitution and weak-head simplification;

  4. every level constraint generated initially, emitted while simplifying object constraints, or emitted by formation-guard compilation belongs to definition 112.12, and each strict equality is oriented and substituted before dependent object simplification continues; and

  5. the returned slice has a ground-determination certificate in the sense of definition 112.30.

A policy-respecting elaboration is a derivation of the mutually inductive term and type relations ΓePa:AandΓAPtypeA, with the auxiliary spine relation Γ(a:A)@qPb:B. The following displayed schemas are the complete definition.

x:AΓ
ΓxPx:A
P-Var
c[]:A is a fully instantiated signature atom
Γc[]Pc[]:A
P-Atom
Γa:Aa,A contain no metavariables
Γ_Pa:A
P-Hole
ΓAPtypeAΓePa:A
Γ(e:A)Pa:A
P-Ann
ΓB typeΓ,x:BC typeΓ,x:BePb:C
Γλϵ,ϱx.ePλϵ,ϱ(x:B).b:x:Bϵ,ϱC
P-Lam
ΓB typeΓ,x:BC typeΓe0Pa:BΓe1Pb:C[a/x]
Γ(e0,e1)P(a,b):x:BC
P-Pair

Rules P-Lam and P-Pair are the two genuinely checking-directed introductions. They display the expected type that generation weak-head inverts, copy the product metadata, and substitute the first pair component into the second component’s type. Atoms and every declared constructor or eliminator instead use P-Atom or the exact signature-head relation below; there is no duplicate introduction route. Type formation belongs to the separate relation below; it is not a term introduction into a guessed common universe.

For a surface vector level, levelP(^)= copies a written level and, when the level is omitted, selects the metavariable-free formation witness stored by the candidate elaboration. The type relation for this policy is exactly:

e_ΓePa:Twhnf(T)=Uu
ΓePtypea
P-Ty-El
p is a well-formed level expression
ΓUpPtypeUp
P-Ty-Univ
D{1,2,N}
ΓDPtypeD
P-Ty-Base
ΓAPtypeAΓe0Pa0:AΓe1Pa1:A
ΓIdA(e0,e1)PtypeIdA(a0,a1)
P-Ty-Id
levelP(^)=ΓAPtypeAΓA:UΓnPn:N
ΓVec[^](A,n)PtypeVec(A,n)
P-Ty-Vec
ΓAPtypeAΓ,x:ABPtypeB
Γx:Aϵ,ϱBPtypex:Aϵ,ϱB
P-Ty-Pi
ΓAPtypeAΓ,x:ABPtypeB
Γx:ABPtypex:AB
P-Ty-Sigma

There is deliberately no P-Ty-Hole. Rule E-Ty-Hole remains part of general constraint generation, but its fresh universe may remain ambiguous, and a mixed-level type need not inhabit any universe at all. The decidable completeness policy therefore requires written annotation types; it still admits explicit mixed-level Π- and Σ-types through P-Ty-Pi/P-Ty-Sigma. The syntactic side condition on P-Ty-El prevents the term-hole rule from reconstructing a whole omitted type by a second route. Rule P-Ty-Vec separately records the particular universe membership required by vector formation, including an omitted vector level determined by guard compilation.

Ordinary applications have no alternative insertion choice:

ΓePa:AΓ(a:A)@qPb:B
ΓeqPb:B
P-App
whnf(A) is not an implicit product
Γ(a:A)@Pa:A
P-Spine-Done
whnf(A)=x:Bimp,ϱCq= or begins with an explicit markerΓd:Bd is the stored omitted core argumentΓ(aimp,ϱd:C[d/x])@qPb:D
Γ(a:A)@qPb:D
P-Spine-Insert
whnf(A)=x:Bϵ,ϱCΓePd:BΓ(aϵ,ϱd:C[d/x])@qPb:D
Γ(a:A)@(eϵ,q)Pb:D
P-Spine-Consume

The remaining rule is indexed by the same finite signature telescope as E-Syn-Head. For the external-level telescope of h, define levelsh,P(^)= positionwise: copy a written level exactly, and at an omitted position select the metavariable-free level witness stored by the candidate elaboration.

h:[u]ΔhRlevelsh,P(^)=Γh(h[];Δh[/u];R[/u])@qPb:B
Γh[^]qPb:B
P-Head

The auxiliary head judgment has exactly the three telescope clauses E-Head-Done, E-Head-Infer, and E-Head-Write, replacing each generation premise by P and replacing each inferred metavariable by its stored metavariable-free core witness. In particular, there is still no omission clause for a written motive. This completes the inductive policy relation and fixes every implicit, external-level, binder, and motive choice used by the completeness proof.

Theorem 112.32 — Completeness for the decidable policy

Let the generation run for e be policy-aligned in a well-formed Timpl context Γ. If a metavariable-free, policy-respecting elaboration a:A exists, the algorithm of this chapter succeeds. Its object substitution is at least as general as the object substitution induced by a, while its residual bound-level assignment is pointwise least among all valid assignments. If the external level arguments of a use that least assignment, the returned core term instantiates in its remaining object metavariables to a term judgmentally equal to a:A.

Proof of Theorem 112.32 — Completeness for the decidable policy

Proof. Induct on the policy-respecting elaboration. At variables, atoms, signature heads, and annotations, generation chooses the same unique rule. In P-Lam and P-Pair, item 1 gives the displayed expected type needed to select the checking rule. At an application, item 2 fixes the number of inserted binders; the kernel term a supplies a solution of every emitted domain equation. Constructor and eliminator cases follow their fixed surface heads, and motives are written inputs.

The induction is simultaneous over the term, type, and spine relations. The type cases are E-Ty-El, E-Ty-Base, E-Ty-Hole, E-Ty-Univ, E-Ty-Pi, E-Ty-Sigma, E-Ty-Id, and E-Ty-Vec; in particular an annotation first generates and solves the constraints of its surface type, and vector formation uses the stored level witness. It constructs a solution of the generated combined constraint state from a. By item 3 and theorem 112.24, the object solver cannot reject a solvable direct-pattern state. Its equality-level pass supplies the unique normalized level substitution before its most general, genuinely typed object substitution, and leaves the accumulated formation bounds. The simultaneous type induction shows that every carried formation guard normalizes under that substitution and that its compiled level premises are satisfied by the candidate. By item 4 and theorem 112.13, the equality and bound phases therefore accept the enlarged residue and return the pointwise least bound assignment. This is an order statement about natural levels, not an instantiation statement: for example, level 0 does not instantiate to level 1. For item 5, induction on the certificate rank assigns each reachable metavariable: lower ranks have already been substituted, and the certified direct flex–rigid equation triggers definition 112.18. The policy excludes flex–flex creation on this slice, so the ranking is defined on every metavariable it mentions. Thus no returned metavariable remains. Object most-generality and level leastness therefore remain separate conclusions. When a uses the least bound assignment, applying the object-factorization result to the returned preterm gives a core term judgmentally equal to a, and corollary 112.29 supplies the kernel judgment. ◻

The theorem does not claim completeness for Timpl surface programming as a whole. It excludes non-pattern higher-order equations, recursive clauses, coercion search, overloading, type classes, tactics, and any heuristic that postpones or backtracks over constraints. It also excludes a fully implicit declaration whose unsolved metavariables a production assistant might choose to generalize.

Remark 112.33 — Ambiguity is rejection

The surface term vnil in synthesis position inserts an element-type metavariable and a level metavariable but generates no equation fixing either. Accepting it would require an unannounced choice of A and u, so item 3 of definition 112.25 leaves it unsolved and therefore rejects it. Either repair is explicit: (vnil:Vec[0](N,0))orvnilVec(A,0). The first writes the external level and synthesizes a closed vector type; the second uses an already formed expected type with its level fixed by the surrounding judgment. Neither changes the kernel rule for vnil.

Exercise 112.8

★☆☆ For each of vnil, λx.x, and (0,_), state whether it synthesizes, checks only against an expected type, or remains ambiguous even while checking. Give one minimal annotation, expected type, or explicit filling of a remaining term hole that repairs every rejected case.

Algorithmic boundaries

The readable core solver traverses trees.

Dynamic higher-order patterns. A constraint that is not presently a pattern can become one after another metavariable is assigned. Treating this observation as unrestricted postponement is unsafe. The terminating simplifier needs a placeholder that records an argument known to be unavailable, and it treats pruning followed by assignment as one indivisible decrease.

Definition 112.34 — Reed's source language and states

For this development only, use Reed’s canonical LF-like language. Its terms are beta-normal and eta-long, hereditary substitution keeps them canonical, and all expressions are well typed after dependencies are erased and every Π is read as an arrow. The relevant grammar is K::=typeΠx:A.K,A,B::=aSΠx:A.B,M,N::=λx.MR,R::=HSu[σ],H::=cxm,S::=()(M;S),σ::=σ,(y/x)σ,(M/x). Here u::(ΨaS) is a contextual metavariable lowered to base type, u[σ] suspends a substitution for its local context, and m is a modal free head that is never instantiated. The placeholder marks an argument that every solution must project away; the book’s postfix substitution convention prints its propagation as [M/x]=, while hereditary application gives [S]=. The brackets in u[σ] remain an inert suspension, not that postfix action.

A problem state is failure , or a modal context Δ together with a finite conjunction P of normal-term, atomic-term, or spine equations, tentative equations uR, and solved assignments uR. A metavariable is active when no assignment uR occurs in P. A ground modal substitution solves P when it makes every equation syntactically equal, respects every solved assignment, and its images contain no placeholder.

A pattern substitution ρ sends local variables to distinct bound variables or to ; it is strong, written ξ, when it contains no placeholder. The inverse ξ1 sends a local variable back to its unique preimage and sends a variable outside the range to . The operation ξid retains identity components and replaces every nonidentity component by . If (/x)ρ, then ρx is the identity substitution on dom(ρ){x}, not merely ρ with one component erased.

The placeholder is semantic information, not a hole to be solved. For example, inversion across a strong pattern may replace a variable outside its range by ; a ground solution is then permitted only if a later projection removes that occurrence.

Definition 112.35 — Dynamic-pattern transitions

Write X^{Y} for an expression context with the displayed occurrence Y, X^rig{Y} when the occurrence is outside every metavariable suspension, and X^srig{Y} when it is also outside arguments to a bound-variable head. Reed’s simplifier nondeterministically uses exactly the following categories; a transition that leaves the state unchanged is forbidden.

  1. Decomposition. Strip equal lambdas, equal rigid heads, and one pair of spine arguments; delete empty-spine equations. Distinct rigid heads fail. A placeholder in a rigid expression context fails: λx.Mλx.Nis replaced byMN,HSHSis replaced bySS,HSHSis replaced by(HH),(M;S)(N;S)is replaced by(MN)(SS),Q^rig{}is replaced by.

  2. Inversion. For strong ξ, u[ξ]Ris replaced byuR[ξ1].

  3. Occurs check. A self-occurrence under a strong pattern is replaceable by a placeholder only where the eventual solution must project it away; a strongly rigid occurrence below a constant is impossible: uHS^{u[ξ]}is replaced byuHS^{},ucS^srig{u[σ]}is replaced by.

  4. Intersection. Replace uu[ξ] by uu[ξid], or delete it when ξid=ξ.

  5. Pruning. Suppose u[ρ] occurs rigidly in an equation, (/x)ρ, and removing x leaves a defined declaration (ΓA)x: x is absent from A and from the types of the retained context. Introduce fresh v::((ΓA)x) by replacing Δ,u::(ΓA)Q^rig{u[ρ]}PbyΔ,u::(ΓA),v::((ΓA)x)(uv[ρx])Q^rig{u[ρ]}P. Retain the equation containing the rigid occurrence. Instantiation of this fresh equation must occur immediately; no other transition may intervene.

  6. Instantiation. If uFV(R), replace (Δ(uR)P)by(Δ[R/u](uR)P[R/u]), using hereditary modal substitution in the context and all constraints.

Success means that only placeholder-free assignments remain. A state to which no category applies is stuck; it is not identified with either success or failure.

Pruning and its forced instantiation are one macro-transition for purposes of termination. The new v has a strictly smaller local context than u, and the old u becomes assigned immediately. Merely introducing v would not decrease the number of active metavariables.

Theorem 112.36 — Reed simplification: exact boundary

For a finite, well-formed problem in the language of definition 112.34, every transition sequence satisfying the pruning discipline terminates in a solved state, a stuck state, or failure. Every step preserves the set of ground solutions on the metavariables present before that step, and preserves well-formedness modulo that state’s residual problem. Consequently a solved final state induces a well-typed most general unifier of the initial problem.

Proof of Theorem 112.36 — Reed simplification: exact boundary

Proof. A term-size-only argument is unavailable. Instantiation may enlarge the surviving equations, while pruning introduces a fresh metavariable and an equation; without the forced following instantiation, the older pruning rule can reproduce its input up to renaming. The decreasing quantity must therefore put active declarations before syntax size.

Order states lexicographically by (number of active metavariables,sum of their local-context sizes,total size of all terms in all equations), where is smaller than every ordinary term. Instantiation strictly decreases the first component. A pruning–instantiation macro-step keeps the first component fixed and strictly decreases the second. Decomposition, inversion, occurs-check replacement, and a changing intersection preserve the first two components and strictly decrease the third. The no-op prohibition excludes equality of measures. Lexicographic order on three natural numbers is well founded, so every sequence terminates.

For solution preservation, decomposition uses injectivity and congruence of canonical syntax. A strong pattern substitution is injective and its inverse is a left inverse on expressions using only variables in its range, which proves inversion in both directions. In the first occurs case, a retained self-occurrence would make a finite solution a proper subterm of itself, so every solution must project it away and may replace it by ; in the strongly rigid constant case projection is unavailable, so repeated unfolding would create arbitrarily many occurrences of the constant. Intersection removes exactly the variables not fixed by the renaming. In a rigid occurrence, a placeholder argument cannot survive, so any solution of a pruning premise is independent of x; it therefore factors through the fresh smaller-context v. Instantiation is ordinary hereditary substitution and its occurs side condition prevents a cyclic definition. These arguments give equality of solution sets on the old metavariables.

Dependent well-formedness is stated modulo all equations in the residual state: two types are equivalent when every ground solution makes them syntactically equal. When decomposition compares two spine arguments, the two spine tails may initially have types containing those different arguments; their enclosing equation makes the types equal modulo the residual problem, which transports both tail typings to one type before the new equation is formed. For terms containing , a completion replaces each placeholder by a well-typed normal term. Inversion completes an out-of-range variable with a fresh contextual metavariable of the required type; the other rules transport typing by hereditary substitution. Hence every transition preserves this well-formedness invariant. In a solved state, solution preservation says that every original solution is an instance of the displayed assignments, which is the MGU factorization claim. ◻

The theorem applies to canonical LF in spine form with contextual modal substitutions, approximate simple typing, hereditary substitution, placeholders, and non-instantiable modal free heads. It does not assert that every solvable problem reaches a solved state: a run may terminate stuck. Reed also permits cyclic dependencies among modal declarations during simplification; an application that requires an acyclic final context must perform a separate cycle check after simplification.

Remark 112.37 — Why the theorem does not transfer to Timpl

Timpl does not have the signature of definition 112.34. Its metavariables may inhabit general dependent types rather than Reed’s lowered base types; its definitional equality includes the Timpl computation rules rather than canonical LF hereditary substitution; and its elaboration state also contains universe equalities and bounds. Identity eliminators, vector indices, and universe normalization may expose or generate constraints not belonging to any category of definition 112.35. Moreover, elaboration itself may create new metavariables and equations, whereas Reed’s termination measure starts from one fixed finite problem.

An extension theorem would therefore have to give a translation or new transition category for every Timpl constraint, prove preservation of scoped typing and problem-relative solutions, and extend the lexicographic measure so that Timpl reduction, level solving, and constraint generation decrease it. Without those proofs, Reed’s theorem justifies the displayed LF-like dynamic pattern subsolver and no termination, completeness, or principality claim for the full Timpl elaborator.

Convention 112.38 — Kov'acs's first-class implicit-function card

This card is separate from Timpl. Its surface language has ordinary and implicit dependent products, abstractions, and applications. Its extended Martin–Löf core adds a type Tel of telescopes, the empty telescope ε, extension (x:A)B¯, and a record type Rec(A¯) of simultaneous arguments. For A¯:Tel and B:Rec(A¯)U, the strictly curried type, abstraction, and application are written {x:A¯}B,λ{x:A¯}.t,t{u:A¯}. They compute by the telescope equations {x:ε}BB[[]/x],{x:(y:A)B¯}C{y:A}{b:B¯}C[(y::b)/x], with the corresponding abstraction and application equations. Thus a meta-headed telescope represents an unknown number of leading implicit domains without changing the surface syntax. The core of this card uses a Russell type-in-type universe; it is not Timpl’s stratified hierarchy.

The obstruction is already present in polymorphic lists. Fix List:UU,nil:{A:U}List(A),cons:{A:U}AList(A)List(A). Check cons(λx.x)nil against List({A:U}AA). The ordinary bidirectional pass first checks λx.x against a meta-headed expected type. Committing there to the explicit type ?A?A makes nil instantiate at that same type, so the final constraint tries to identify {A:U}AA with an explicit arrow and fails. The failure is not missing ordinary implicit-application insertion: that insertion has already supplied fresh arguments to cons and nil. It is the earlier, irreversible choice not to insert an implicit abstraction.

Definition 112.39 — Delayed implicit-abstraction insertion

In the card of convention 112.38, retain the ordinary insertion rule: when inference exposes t:{x:A}B and the surface spine has no written implicit argument, insert a fresh ?u:A and continue from t{?u}:B[?u/x].

Add one checking clause for a meta-headed expected type ?α[u¯]. Create a fresh telescope metavariable ?Δ:Tel, extend the local context by x:Rec(?Δ), infer the source term there, and run the ordinary implicit-application insertion just described, obtaining t:B. Add the source algorithm’s constancy constraint that records whether B depends on x, unify ?α[u¯]{x:?Δ}B, and return λ{x:?Δ}.t. If the codomain is independent of x, the constancy constraint solves ?Δ with ε, so the wrapper computes away. In the polymorphic-list trace, unification instead solves the telescope with the one-entry domain (A:U)ε, and the inserted wrapper becomes the required implicit abstraction.

Proposition 112.40 — Soundness and erasure of the source elaborator

For the surface and core languages frozen in convention 112.38, Kovács’s checking and inference functions have the following proved consequences.

  1. Every returned checking or inference result satisfies its specified core typing judgment.

  2. Erasing a returned core term yields its input surface term with holes filled and only implicit abstractions and applications inserted; the delayed strictly curried wrapper is included among those inserted abstractions.

The source proves no elaboration completeness theorem. Its functions are partial and may fail or diverge because the chosen core has type-in-type. Curried-application insertion for inferring polymorphic arguments is only the future-work sketch of Section 7.3; it is not covered by the two consequences and is not part of either proved algorithm.

Proof of Proposition 112.40 — Soundness and erasure of the source elaborator

Proof. We prove both items simultaneously. For every successful recursive call keep two invariants. First, if the input metacontext is Θ0, the returned metasubstitution has type θ:ΘΘ0 and the returned core term is typed after applying θ to the input context. Second, if || forgets core annotations and erases implicit applications and implicit or strictly curried abstractions, then |t| is the input surface term with each surface hole replaced by the erasure of its returned solution. We establish the invariants by mutual structural induction on the checking and inference calls, with an inner induction on insertion.

The auxiliary operations preserve the first invariant. Ordinary substitution preserves core typing. Functoriality of metasubstitution gives u[θ1][θ2]=u[θ1θ2], so the substitution thread printed by a later recursive call has the required source and target. The specification of freshMetaΘΓ(A) extends Θ by ?α:ΓA, returns weakening p:(Θ,?α:ΓA)Θ, and types ?αvarsΓ:A[p]. Successful unification returns θ with A[θ]B[θ]; conversion therefore changes the inferred type to the expected type. These four facts prove every use of substitution, freshMeta, and unify below.

For insertion, suppose the input is t:{x:A}B. Freshness gives u:A; implicit application gives t{u}:B[u/x], and the inner induction applies to the residual result. The non-product clause returns its typed input. The guarded clause for an implicit abstraction also returns its input. Hence insertion preserves typing. Its only syntactic change is an implicit application, so it preserves the erasure invariant.

We now inspect the surface constructors. A variable is typed by lookup, and the universe is typed by the source’s type-in-type rule; both erase to themselves. For an explicit or implicit product, the two checking induction hypotheses type the domain and codomain at the universe; product formation types the returned core product. For an explicit or implicit application, the inference hypothesis types the head, insertion preserves that typing, two fresh universe-valued metavariables supply a prospective domain and codomain, and unification converts the head type to the corresponding product. The checking hypothesis types the argument at the converted domain, so application has the substituted codomain. The erasure calculation is |t{u¯}u|=|t||u|=tu; for a written implicit application the retained brace distinguishes the written application from applications created by insertion.

For an abstraction checked against a matching product, the checking induction hypothesis types its body in the extended context and product introduction types the wrapper. For an inferred abstraction, freshness types its domain, the inference hypothesis and insertion type its body, and product introduction gives the returned type. The inserted implicit-wrapper checking clause for a non-abstraction is the same argument without changing the surface syntax: erasure removes the fresh wrapper. A let-expression uses the three induction hypotheses for its annotation, definition, and body; metasubstitution composition aligns their successively transformed contexts, and the core let rule types the result. Erasure distributes through let. A checking hole is exactly the term returned by freshMeta; an inferred hole first creates its fresh type and then its fresh inhabitant. Thus both are typed and their erasures are permitted hole fillings. The fallback checking clause combines the inference invariant, insertion lemma, and unification conversion, and changes no surface constructor.

It remains to check the delayed clause of definition 112.39. Freshness types ?Δ:Tel. By the inference and insertion invariants, t:B in Γ,x:Rec(?Δ). The constancy declaration only restricts later metasubstitutions and leaves that judgment valid. Strictly curried introduction therefore gives λ{x:?Δ}.t:{x:?Δ}B; successful unification converts this type to ?α[u¯]. Its erasure is |t|, because the wrapper was inserted rather than written. These cases exhaust the checking, inference, insertion, and delayed clauses, proving both items.

No induction just given supplies a successful run for a typable surface term: it starts from a successful call. Nor does it prove termination of normalization or unification in the type-in-type core. Curried-application insertion is absent from the inspected clauses. The three excluded claims therefore do not follow. ◻

A polymorphically recursive constraint.

Take the indexed nesting signature nil:Nest(A),cons:ANest(A×A)Nest(A). With the written scheme size:{A:Uu}Nest(A)N, the constructor branch receives xs:Nest(A×A), and its recursive call instantiates size at A×A. The call is then checked by ordinary equations. Remove the scheme and give the recursive occurrence one monomorphic provisional type Nest(?X)N. Splitting its input by cons gives the tail type Nest(?X×?X). The recursive call therefore generates ?X?X×?X, which fails the occurs check. The polymorphic program does not solve that equation; it avoids it by instantiating one quantified scheme twice.

Inferring the missing scheme would therefore ask the solver to introduce a quantifier inside an unknown and to compare its distinct instances. A first-order unifier assigns monotypes, while the contextual-pattern solver of this chapter assigns terms at one declared dependent type. Neither rule invents the required scheme. This is the concrete reason recursive clauses are absent from definition 112.2. This trace establishes only that boundary of the Timpl policy; it imports no semi-unification or undecidability result.

Exercise 112.9

★★☆ For the displayed Nest signature, trace the constructor branch of size. First use its written polymorphic scheme and state the instance selected at the recursive call. Then replace the recursive assumption by the monotype Nest(?X)N, generate the recursive-call equation for ?X, and identify the exact solver check that fails. Explain why higher-order pattern assignment does not repair the failure.

A source-firewalled CIC comparison. UniCoq is a different unifier: its source calculus is CIC with definitions, inductives, fixpoints, flexible and rigid universe instances, canonical structures, and controlled backtracking. The comparison uses the journal specification’s universe rules in Section 11, canonical-structure rules in Sections 8 and 12, and correctness discussion in Section 15 [ZS17]. None of its judgments is identified with the Timpl state of definition 112.5.

Three traces expose the boundary. First, a universe-polymorphic identity is freshened at its two occurrences in self-application. If their flexible levels are and κ, checking the argument generates κ<; reusing one monomorphic level instead would demand both i<j and j<i. The incompatible and identical explicit-instance cases therefore receive different outcomes. Second, the canonical-structure membership example begins with luntag(list_of(?f))[y1]++[y2]. The default key selects rightTag; the projector key then selects right_proof and generates its arguments. In the smaller projector case, the solver must find a canonical record before checking an argument at its projected type. This is overloading search, not principal pattern unification.

Third, the natural type-preservation conjecture for the UniCoq procedure is false in the presence of the fixpoint guard. In mathematical notation, its published term has the following three local bindings: h:(N0)N0:=?X1,T:=fix f(x:N):0:=hfx,p:h=idN0:=refl(?X4),followed by T0. The equality for p solves ?X1 with idN0. Substitution changes the fixpoint body to idfx, which reduces to fx: the recursive call receives the original argument, not a structural subterm. Unification has produced convertible endpoints, but the kernel therefore rejects the instantiated fixpoint. Ziliani and Sozeau state no correctness proof for the full procedure [ZS17]. These comparison traces prove neither soundness nor completeness and do not alter theorem 112.24, theorem 112.32.

Exercise 112.10

★★★ Reconstruct the three UniCoq comparison traces from the source-firewalled card: the flexible-level inequality for polymorphic self-application, the two canonical-structure selections for list membership, and the delayed instantiation that violates the fixpoint guard. For each trace, name the feature absent from Timpl and state why the trace supplies no counterexample to this chapter’s soundness or policy-completeness theorem.

Sources for the construction

Bidirectional typing supplies the information-flow discipline used in definition 112.6; the surface/core distinction is implemented at small scale in pi-forall [DK19, Wei22]. Gundry’s contextual unification gives the dependency-ordered metacontext, flex–rigid abstraction, flex–flex intersection, and sharply bounded pattern completeness used here [Gun13]. The direct fragment in this chapter is deliberately smaller so that theorem 112.24 has a direct termination proof. The level graph solver instantiates the universe-expression calculation and correctness theorem of section 74.4, proposition 74.10; it is independent of term unification. Its inequality edges come from U-Hier and the nullary closure rules, not from U-Cumul.

Three supplemental sources have narrower jobs. Pfenning proves existence and uniqueness, up to his pattern renamings and permutations, for the exact restricted CoC pattern syntax in his paper [Pfe91]; this chapter does not identify that equivalence with its contextual metacontext or transfer the result to Timpl. Baader and Snyder supply the first-order notions of substitution, problem-relative comparison, complete sets of unifiers, and term-DAG output used in the starred seminar [BS01]; their theorems are not dependent elaboration theorems.

Suggested first pass.

None of these problems is a prerequisite for a later chapter. Begin with exercise 112.11, then complete exercise 112.14.

Exercise 112.11

★★☆ Use the declaration and context map:[u,v]{A:Uu}{B:Uv}{n:N}(AB)Vec(A,n)Vec(B,n),Γ=A:Uu,B:Uv,n:N,f:AB,xs:Vec(A,n). Repeat the trace of section 112.6 for mapfxs. List the level metavariables and contextual term metavariables separately, each in creation order. Give the rigid equations generated by the vector argument, the strict level equalities and their normalized assignments, and the final metavariable-free core spine.

Exercise 112.12

★★☆ Construct one well-typed constraint for each of four failures: rigid-head clash, occurs check, scope escape, and non-pattern application. Prove that the first three have no solution of the declared kind. For the fourth use (112.7): prove that its two solutions are incomparable and form its complete set of unifiers, and distinguish that non-unitarity claim from unrestricted higher-order undecidability.

Exercise 112.13

★★★ Specify a graph representation for the rigid first-order constraints of definition 112.15. State a relation between graph nodes and tree terms, and prove that one graph merge preserves exactly the tree solutions. Do not claim the Paterson–Wegman complexity bound unless the representation and machine operations satisfy its hypotheses.

Exercise 112.14

★★★ Practical project.timpl-elaborator Implement in Agda or Kappa the reusable solver fragment below. The resulting program is a finite acceptance slice of definition 112.6, definition 112.15, definition 112.18, definition 112.12, not a parser or a full Timpl elaborator. Represent first-order terms by bound variables, arbitrary-arity rigid heads, and contextual metavariables applied to variable spines. Represent declarations by metavariables with finite list-valued telescopes, and represent a problem by an equation worklist and an ordered substitution. Implement rigid decomposition and clash. Implement flex–rigid assignment for a distinct-variable spine of the declared arity: check occurrence and scope, abstract the right-hand side to the declaration telescope by parallel renaming, and instantiate the stored body when applying the substitution. Reject flex–flex equations and non-pattern spines as outside this fragment.

Represent a finite level problem by integer-weighted edges p+cq. Detect a positive-weight cycle of arbitrary length by graph relaxation, rather than by matching a fixed edge-list shape. Maintain the invariant that every stored assignment is scoped by its declaration telescope and that every processed worklist uses the accumulated substitution. Keep ambiguity, occurs, scope, rigid clash, non-pattern input, positive level cycles, and final kernel acceptance as distinct decisions.

The program must traverse the following machine-readable corpus and emit either a metavariable-free core term with its type or a rejection category. The named acceptance corpus is:

  1. append-ok: the context and surface term of (112.1), with exact core result (112.12);

  2. vnil-annotated-ok: the annotated surface term (vnil:Vec[0](N,0)), producing the explicit core vnil[0]{N}:Vec(N,0);

  3. vnil-ambiguous: bare vnil, rejected as unsolved-meta;

  4. occurs-bad: ?α[x]suc(?α[x]), rejected as occurs;

  5. scope-bad: ?α[x]y for ydom(x:N), rejected as scope; and

  6. level-cycle-bad: r+1s,s+1r, rejected as level-cycle.

Check every successful output with the independent finite Timpl kernel model. As a mutation test, disable the scope guard in flex–rigid assignment: the scope-bad record must then reach that kernel model and be rejected there, demonstrating that an elaborator’s acceptance without rechecking is not the invariant. The observable result is the six outcome records and the exact core spine for append-ok. Add non-public checks for a telescope of length at least three and a positive cycle of length at least three.

This project implements first-order syntactic rigid/flex–rigid solving for distinct-variable spines and finite difference-constraint cycle detection. It does not implement binders in the term syntax, dependent typing, definitional equality, flex–flex intersection, postponement, search, or constraint generation from arbitrary surface programs. Its executions provide no proof of theorem 112.24, corollary 112.29, theorem 112.32.

Search the book

Type to search the local edition.