Lectures onType Theory
ch:elaboration: ch:elaboration
appendix sectionsolutions

ch:elaboration: ch:elaboration

Exercise 112.1.

The first equation orients to ?α:=[x:N]x. The body has type N in the declaration telescope x:N, so substitution at the occurrence gives x as required. For the third equation, typing the right side in the full declaration telescope gives ?β:=[x:N,y:2]x. A legal contextual definition may ignore a telescope variable; its premise is typing in the whole telescope, not occurrence of every variable in the body.

The middle equation does not orient. Its right-hand side is well typed at N in the ambient context, but its Boolean scrutinee is the free variable y. Hence it is not a term of type N in the smaller telescope x:N. The failed premise of definition 112.3 is x:Na:N for the proposed body a; equivalently, this is a scope failure, not an occurs failure.

Exercise 112.2.

Pair checking first checks 0 against N. Substituting the returned core term for n makes the second expected type IdN(n,0)[0/n]=IdN(0,0). Thus refl(0) checks, and the original pair is accepted.

With first component suc(0), the second expected type is instead IdN(suc(0),0). The introduction refl(0) has native type IdN(0,0). Rigid decomposition of the required type equality reaches the endpoint constraint suc(0)0:N. Its heads are distinct natural-number constructors, so rigid simplification rejects it.

Exercise 112.3.

The incoming bounds at r give r=max(u+1,v). The bounds at s then give s=boundsmax(r+1,v+3)=valueofrmax(u+2,v+1,v+3)=absorptionmax(u+2,v+3). These are least because every solution must dominate every path weight into the corresponding vertex, and the displayed maxima attain all four bounds.

After adding s+1r, the edges r1s1r form a cycle of total weight 2. Summing its inequalities yields r+2r, an impossible inequality of natural levels. This is the positive-cycle certificate.

Exercise 112.4.

Left-to-right heterogeneous decomposition first equates the outer types, Vec(A,suc(?p[π]))Vec(A,suc(m)):Uu. Rigid decomposition and successor injectivity emit ?p[π]m:N. The direct contextual assignment is ?p:=[Γ0]m. After substitution, both constructor results have type Vec(A,suc(m)), and the two head entries are the same term a:A, so their equation deletes reflexively. Before comparing the final arguments, use the solved index equation to convert xs:Vec(A,?p[π])toxs:Vec(A,m). The tail equation is therefore the homogeneous judgment xsys:Vec(A,m). If the tails were compared first, their available types would be Vec(A,?p[π]) and Vec(A,m). Those are not yet judgmentally the same type, so no homogeneous typed equation could be formed. The earlier index equation supplies exactly the context conversion needed by the later component.

Exercise 112.5.

The pattern assignment is ?α:=[x:N,y:2](x,suc(x)). In that telescope, x:N and suc(x):N. Consequently the pair has type n:NN, and instantiating the abstraction at [x,y] beta-reduces to the right-hand side of the constraint. The pattern condition asks that the occurrence apply ?α to a variable renaming of its telescope. It does not require the solution body to depend on every formal parameter, so the unused y is harmless.

Exercise 112.6.

For the first equation, only the first argument position agrees. Introduce ?β:[r:NN] and set ?α:=[r:N,s:N]?β[r]. Both sides reduce to ?β[x], so the retained telescope is r:N. For the second equation, only the second position agrees. With ?γ:[s:NN], set ?α:=[r:N,s:N]?γ[s]. Both sides now reduce to ?γ[y], and the retained telescope is s:N. The factorization argument of lemma 112.23 makes these solutions most general: any solution must ignore precisely the formal position varied independently across the two occurrences.

If the result type is Vec(N,y), the first constraint is heterogeneous: its occurrence types are Vec(N,y) and Vec(N,z). Type-first simplification reaches the rigid equation yz:N, so the solver returns unsatisfiable before attempting an intersection. The second constraint gives identical occurrence types Vec(N,y); it reaches flex–flex intersection, retains the second parameter, and introduces a fresh metavariable of result type Vec(N,s).

Exercise 112.7.

For the signature with base type o and sole constant c:o, two solutions of ?F[c]c:o are ?F:=[x:o]xand?F:=[x:o]c. Neither unifier is an instance of the other. Later substitutions affect only residual metavariables. They cannot turn the bound occurrence x in the first body into the rigid constant c, or turn the rigid constant in the second body into x.

There is no third unifier above both. Normalize its body at type o in context x:o. With no eliminator or other constant, its canonical forms are x, c, or a neutral headed by a residual metavariable. Replacing x by c turns the first two into c, while a residual neutral stays neutral and cannot solve the equation without an additional constraint. Hence the two displayed bodies are the complete set of unifiers, modulo judgmental equality and residual renaming, and neither is most general.

The flex–rigid proof abstracts along a bijective variable renaming of the declaration telescope. The argument c is rigid, not that renaming, so equality at the observed input gives no equality of abstractions. This is a proof of non-unitarity; undecidability of unrestricted higher-order unification is a separate source result.

Exercise 112.8.

Bare vnil does not synthesize: its omitted element type and level receive no determining equation. It checks against an expected vector type whose index is zero, for example vnilVec(N,0), or synthesizes after the level-explicit annotation (vnil:Vec[0](N,0)).

The abstraction λx.x also does not synthesize, because its domain is absent. It checks against NN, or synthesizes after the annotation (λx.x:NN).

The pair (0,_) does not synthesize, since pair introduction is checking-directed. Against n:NN, the first component checks and the second hole is assigned expected type N, but its term metavariable remains unsolved. Thus it remains ambiguous even while checking. No type annotation can choose a term for that hole under definition 112.25; a minimal repair must also fill it, for example ((0,0):n:NN). This last case is the boundary between missing type information, repaired by an expected type, and missing program information, repaired by a term.

Exercise 112.9.

In the cons branch the constructor indices give A:Uu,x:A,xs:Nest(A×A). The written polymorphic scheme may be instantiated independently at each recursive occurrence. The call on xs selects the instance size{A×A}:Nest(A×A)N, so its domain is exactly the known type of xs.

Under the monomorphic provisional assumption size:Nest(?X)N, checking the defining function at the constructor pattern gives xs:Nest(?X×?X). Checking that recursive argument against the provisional domain generates ?X?X×?X. An attempt to orient this equation would define the type metavariable using a type that contains it. The occurs check rejects the cycle.

Contextual pattern assignment cannot help. Its flexible heads are term metavariables at a fixed declared type, applied to variable renamings. Here the missing object is a quantified type scheme whose two instances have different monotypes. No rule in the direct fragment introduces that quantifier, so the problem lies outside the solver rather than furnishing a failed pattern equation.

Exercise 112.10.

Freshening polymorphic self-application gives the instances pid[] and pid[κ]. The second occurrence is an argument to the first, so the universe containing its type must be below the first occurrence’s universe: κ<. If one monomorphic level were reused, the result would instead contain a strict cycle. UniCoq may distinguish flexible from rigid universe instances; Timpl has only the stratified equality-and-bound problems of definition 112.12. The example therefore illustrates a richer source language, not a failure of the proved graph solver.

For list membership, rigid decomposition first reduces the overloaded goal to luntag(list_of(?f))[y1]++[y2]. There is no direct canonical key pairing luntag with append, so the default key selects rightTag. The residual equation has a list_of projector against a rightTag-headed term; that key selects right_proof, after which fresh metavariables are generated for the instance’s arguments. Timpl has no canonical-structure database or overloading search. Its theorem is conditional on one fixed signature head and deterministic insertion, so this search trace is outside its statement.

In the guard example, write the published local bindings as h:(N0)N0:=?X1,T:=fix f(x:N):0:=hfx,p:h=idN0:=refl(?X4),then evaluate T0. The equality for p forces ?X1:=idN0. Applying this substitution to the provisional body gives hfxidN0fxfx. The recursive argument is still x, not a structural subterm of x. Conversion of the unification endpoints survives, but the CIC kernel’s syntactic guard check rejects the instantiated fixpoint. The exact archived plugin replay in appendix D confirms the source tests, but does not turn this counterexample into a metatheorem. Timpl excludes recursive clauses and fixpoint unification in convention 112.1; its successful output is instead independently checked against the displayed nonrecursive signature. Thus the published counterexample refutes a natural correctness conjecture for the richer procedure and leaves this chapter’s soundness and bounded completeness claims untouched.

Exercise 112.11.

Use the implicit declaration map:[u,v]{A:Uu}{B:Uv}{n:N}(AB)Vec(A,n)Vec(B,n). In a context containing A:Uu, B:Uv, n:N, f:AB, and xs:Vec(A,n), implicit saturation creates, in order, the level context ?A,?B and then the contextual term metacontext ?X:[ΓU?A],?Y:[ΓU?B],?p:[ΓN]. The initial core spine is map[?A,?B]{?X}{?Y}{?p}. Checking f against ?X?Y rigidly decomposes its known type AB, giving the two term equations ?XA,?YB. Orienting ?X:=A and ?Y:=B checks each body against its contextual metavariable’s declared universe. Decomposing those universe equations emits the strict level equations ?ALu,?BLv. Before applying that substitution, the vector argument generates Vec(?X,?p)Vec(A,n), whose rigid components are ?XA and ?pn; after the function constraints have been substituted, only ?pn is new. The normalized strict level assignments are therefore u and v. The type-formation judgment establishes the mixed-level declaration without assigning the whole product to an enclosing universe. The metavariable-free result is map[u,v]{A}{B}{n}fxs:Vec(B,n). The object equations fix ?X,?Y,?p, while the strict level equations fix ?A,?B. No choice remains.

Exercise 112.12.

The following four constraints are well typed in the indicated metacontexts.

  1. 0suc(0):N is a rigid-head clash.

  2. For ?α:[x:NN], ?α[x]suc(?α[x]):N triggers the occurs check.

  3. In x:N,y:N, for ?α:[x:NN], ?α[x]y:N is a scope escape.

  4. For ?F:[x:oo] in the signature with the sole constant c:o, ?F[c]c:o is a non-pattern application.

The first has no solution because distinct canonical constructors of N cannot be judgmentally equal. A solution of the second would be a finite acyclic term equal to a term containing itself as a proper subterm; constructor inversion would reproduce the same demand below one suc, so no such contextual definition exists. A legal solution of the third must be typed in the telescope x:N, but the rigid ambient variable y is not in that telescope and substitution cannot remove it. Hence no scoped solution exists.

The fourth has the two solutions ?F:=[x]x and ?F:=[x]c. They are incomparable because residual instantiation cannot replace a bound variable by a rigid constant or conversely. They are also complete: a beta-normal, eta-long body of type o in context x:o is x, c, or a residual neutral; after substituting c, a residual neutral cannot become the rigid canonical form c. Thus the problem is non-unitary. The direct solver therefore reports the problem outside its fragment; this protects the stated principality boundary without asserting that either solution is unsound. Unrestricted higher-order undecidability is a separate, stronger source theorem.

Exercise 112.13.

Represent a rigid first-order term by a node of a finite acyclic directed graph. A node is labelled by an ordinary variable, a metavariable leaf, or a rigid symbol F together with an ordered vector of child nodes of the symbol’s arity. Sharing is permitted. A state consists of this graph, a union–find partition, and a queue of node pairs still to be equated.

For a substitution θ of the metavariable leaves, write G,nθt when recursively unfolding node n, replacing each metavariable leaf by its θ-image, yields the tree term t. Say that θ solves a graph state when it gives equal unfolded terms to every pair in the queue and to every pair of nodes in one union–find class. This relation records the mathematical content of a class; path compression and representative choice are absent from it.

Consider one work item (n,m) with equal rigid labels F and child vectors (n1,,nk) and (m1,,mk). The graph step unions the classes of n,m, removes (n,m), and enqueues every (ni,mi). We prove preservation in both directions. If θ solves the old state, then F(t1,,tk)=F(u1,,uk),G,niθti,G,miθui. Rigid injectivity gives ti=ui for every i. Thus every new child pair and the new parent class are satisfied. Conversely, if θ solves the new state, every ti=ui; congruence gives equality of the two parent unfoldings, so the removed work item is satisfied. All untouched classes and work items have identical interpretations. The step therefore preserves exactly the tree solutions. Different rigid labels instead give the empty solution set by rigid-head disjointness.

This is a refinement lemma for one merge. It supplies neither the global algorithm nor the Paterson–Wegman bound: the latter additionally requires its specific graph representation, scheduling, and constant-time machine operations.

Search the book

Type to search the local edition.