Exercise 112.1.
The first equation orients to ?𝛼:=[𝑥:ℕ]𝑥. The body has type ℕ in the declaration telescope 𝑥 :ℕ, so substitution at the occurrence gives 𝑥 as required. For the third equation, typing the right side in the full declaration telescope gives ?𝛽:=[𝑥:ℕ,𝑦:𝟐]𝑥. 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 ℕ in the ambient context, but its Boolean scrutinee is the free variable 𝑦. Hence it is not a term of type ℕ in the smaller telescope 𝑥 :ℕ. The failed premise of definition 112.3 is 𝑥 :ℕ ⊢𝑎 :ℕ for the proposed body 𝑎; equivalently, this is a scope failure, not an occurs failure.
Exercise 112.2.
Pair checking first checks 𝟢 against ℕ. Substituting the returned core term for 𝑛 makes the second expected type 𝖨𝖽ℕ(𝑛,𝟢)[𝟢/𝑛]=𝖨𝖽ℕ(𝟢,𝟢). Thus 𝗋𝖾𝖿𝗅(𝟢) checks, and the original pair is accepted.
With first component 𝗌𝗎𝖼(𝟢), the second expected type is instead 𝖨𝖽ℕ(𝗌𝗎𝖼(𝟢),𝟢). The introduction 𝗋𝖾𝖿𝗅(𝟢) has native type 𝖨𝖽ℕ(𝟢,𝟢). Rigid decomposition of the required type equality reaches the endpoint constraint 𝗌𝗎𝖼(𝟢)≐𝟢:ℕ. Its heads are distinct natural-number constructors, so rigid simplification rejects it.
Exercise 112.3.
The incoming bounds at 𝑟 give 𝑟=max(𝑢+1,𝑣). The bounds at 𝑠 then give 𝑠𝑏𝑜𝑢𝑛𝑑𝑠=max(𝑟+1,𝑣+3)𝑣𝑎𝑙𝑢𝑒𝑜𝑓𝑟=max(𝑢+2,𝑣+1,𝑣+3)𝑎𝑏𝑠𝑜𝑟𝑝𝑡𝑖𝑜𝑛=max(𝑢+2,𝑣+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 𝑠 +1 ≤𝑟, the edges 𝑟1→𝑠1→𝑟 form a cycle of total weight 2. Summing its inequalities yields 𝑟 +2 ≤𝑟, 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, 𝖵𝖾𝖼(𝐴,𝗌𝗎𝖼(?𝑝[𝜋]))≐𝖵𝖾𝖼(𝐴,𝗌𝗎𝖼(𝑚)):U𝑢. Rigid decomposition and successor injectivity emit ?𝑝[𝜋]≐𝑚:ℕ. The direct contextual assignment is ?𝑝 :=[Γ0]𝑚. After substitution, both constructor results have type 𝖵𝖾𝖼(𝐴,𝗌𝗎𝖼(𝑚)), and the two head entries are the same term 𝑎 :𝐴, so their equation deletes reflexively. Before comparing the final arguments, use the solved index equation to convert 𝑥𝑠:𝖵𝖾𝖼(𝐴,?𝑝[𝜋])to𝑥𝑠:𝖵𝖾𝖼(𝐴,𝑚). The tail equation is therefore the homogeneous judgment 𝑥𝑠≐𝑦𝑠:𝖵𝖾𝖼(𝐴,𝑚). If the tails were compared first, their available types would be 𝖵𝖾𝖼(𝐴,?𝑝[𝜋]) and 𝖵𝖾𝖼(𝐴,𝑚). 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 ?𝛼:=[𝑥:ℕ,𝑦:𝟐](𝑥,𝗌𝗎𝖼(𝑥)). In that telescope, 𝑥 :ℕ and 𝗌𝗎𝖼(𝑥) :ℕ. Consequently the pair has type ∑𝑛:ℕℕ, and instantiating the abstraction at [𝑥,𝑦] 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 𝑦 is harmless.
Exercise 112.6.
For the first equation, only the first argument position agrees. Introduce ?𝛽 :[𝑟 :ℕ ⊢ℕ] and set ?𝛼:=[𝑟:ℕ,𝑠:ℕ]?𝛽[𝑟]. Both sides reduce to ?𝛽[𝑥], so the retained telescope is 𝑟 :ℕ. For the second equation, only the second position agrees. With ?𝛾 :[𝑠 :ℕ ⊢ℕ], set ?𝛼:=[𝑟:ℕ,𝑠:ℕ]?𝛾[𝑠]. Both sides now reduce to ?𝛾[𝑦], and the retained telescope is 𝑠 :ℕ. 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 𝖵𝖾𝖼(ℕ,𝑦), the first constraint is heterogeneous: its occurrence types are 𝖵𝖾𝖼(ℕ,𝑦) and 𝖵𝖾𝖼(ℕ,𝑧). Type-first simplification reaches the rigid equation 𝑦 ≐𝑧 :ℕ, so the solver returns unsatisfiable before attempting an intersection. The second constraint gives identical occurrence types 𝖵𝖾𝖼(ℕ,𝑦); it reaches flex–flex intersection, retains the second parameter, and introduces a fresh metavariable of result type 𝖵𝖾𝖼(ℕ,𝑠).
Exercise 112.7.
For the signature with base type 𝑜 and sole constant 𝑐 :𝑜, two solutions of ?𝐹[𝑐] ≐𝑐 :𝑜 are ?𝐹:=[𝑥:𝑜]𝑥and?𝐹:=[𝑥:𝑜]𝑐. Neither unifier is an instance of the other. Later substitutions affect only residual metavariables. They cannot turn the bound occurrence 𝑥 in the first body into the rigid constant 𝑐, or turn the rigid constant in the second body into 𝑥.
There is no third unifier above both. Normalize its body at type 𝑜 in context 𝑥 :𝑜. With no eliminator or other constant, its canonical forms are 𝑥, 𝑐, or a neutral headed by a residual metavariable. Replacing 𝑥 by 𝑐 turns the first two into 𝑐, 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 𝑐 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 𝗏𝗇𝗂𝗅 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 𝗏𝗇𝗂𝗅⇐𝖵𝖾𝖼(ℕ,𝟢), or synthesizes after the level-explicit annotation (𝗏𝗇𝗂𝗅 :𝖵𝖾𝖼[0](ℕ,𝟢)).
The abstraction 𝜆𝑥. 𝑥 also does not synthesize, because its domain is absent. It checks against ℕ →ℕ, or synthesizes after the annotation (𝜆𝑥. 𝑥 :ℕ →ℕ).
The pair (𝟢,_) does not synthesize, since pair introduction is checking-directed. Against ∑𝑛:ℕℕ, the first component checks and the second hole is assigned expected type ℕ, 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 ((𝟢,𝟢):∑𝑛:ℕℕ). 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 𝖼𝗈𝗇𝗌 branch the constructor indices give 𝐴:U𝑢,𝑥:𝐴,𝑥𝑠:𝖭𝖾𝗌𝗍(𝐴×𝐴). The written polymorphic scheme may be instantiated independently at each recursive occurrence. The call on 𝑥𝑠 selects the instance 𝗌𝗂𝗓𝖾{𝐴×𝐴}:𝖭𝖾𝗌𝗍(𝐴×𝐴)→ℕ, so its domain is exactly the known type of 𝑥𝑠.
Under the monomorphic provisional assumption 𝗌𝗂𝗓𝖾 :𝖭𝖾𝗌𝗍(?𝑋) →ℕ, checking the defining function at the constructor pattern gives 𝑥𝑠 :𝖭𝖾𝗌𝗍(?𝑋 ×?𝑋). Checking that recursive argument against the provisional domain generates ?𝑋≐?𝑋×?𝑋. 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 𝗉𝗂𝖽[ℓ] and 𝗉𝗂𝖽[𝜅]. 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 𝗅𝗎𝗇𝗍𝖺𝗀(𝗅𝗂𝗌𝗍_𝗈𝖿(?𝑓))≐[𝑦1]++[𝑦2]. There is no direct canonical key pairing 𝗅𝗎𝗇𝗍𝖺𝗀 with append, so the default key selects 𝗋𝗂𝗀𝗁𝗍𝖳𝖺𝗀. The residual equation has a 𝗅𝗂𝗌𝗍_𝗈𝖿 projector against a 𝗋𝗂𝗀𝗁𝗍𝖳𝖺𝗀-headed term; that key selects 𝗋𝗂𝗀𝗁𝗍_𝗉𝗋𝗈𝗈𝖿, 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 ℎ:(ℕ→𝟎)→ℕ→𝟎:=?𝑋1,𝑇:=𝖿𝗂𝗑 𝑓(𝑥:ℕ):𝟎:=ℎ𝑓𝑥,𝑝:ℎ=𝗂𝖽ℕ→𝟎:=𝗋𝖾𝖿𝗅(?𝑋4),then evaluate 𝑇𝟢. The equality for 𝑝 forces ?𝑋1 :=𝗂𝖽ℕ→𝟎. Applying this substitution to the provisional body gives ℎ𝑓𝑥⟼𝗂𝖽ℕ→𝟎𝑓𝑥⟶𝑓𝑥. The recursive argument is still 𝑥, not a structural subterm of 𝑥. 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 𝗆𝖺𝗉:[𝑢,𝑣]{𝐴:U𝑢}→{𝐵:U𝑣}→{𝑛:ℕ}→(𝐴→𝐵)→𝖵𝖾𝖼(𝐴,𝑛)→𝖵𝖾𝖼(𝐵,𝑛). In a context containing 𝐴 :U𝑢, 𝐵 :U𝑣, 𝑛 :ℕ, 𝑓 :𝐴 →𝐵, and 𝑥𝑠 :𝖵𝖾𝖼(𝐴,𝑛), implicit saturation creates, in order, the level context ?ℓ𝐴,?ℓ𝐵 and then the contextual term metacontext ?𝑋:[Γ⊢U?ℓ𝐴],?𝑌:[Γ⊢U?ℓ𝐵],?𝑝:[Γ⊢ℕ]. The initial core spine is 𝗆𝖺𝗉[?ℓ𝐴,?ℓ𝐵]{?𝑋}{?𝑌}{?𝑝}. Checking 𝑓 against ?𝑋 →?𝑌 rigidly decomposes its known type 𝐴 →𝐵, giving the two term equations ?𝑋≐𝐴,?𝑌≐𝐵. Orienting ?𝑋 :=𝐴 and ?𝑌 :=𝐵 checks each body against its contextual metavariable’s declared universe. Decomposing those universe equations emits the strict level equations ?ℓ𝐴≐𝖫𝑢,?ℓ𝐵≐𝖫𝑣. Before applying that substitution, the vector argument generates 𝖵𝖾𝖼(?𝑋,?𝑝)≐𝖵𝖾𝖼(𝐴,𝑛), whose rigid components are ?𝑋 ≐𝐴 and ?𝑝 ≐𝑛; after the function constraints have been substituted, only ?𝑝 ≐𝑛 is new. The normalized strict level assignments are therefore 𝑢 and 𝑣. The type-formation judgment establishes the mixed-level declaration without assigning the whole product to an enclosing universe. The metavariable-free result is 𝗆𝖺𝗉[𝑢,𝑣]{𝐴}{𝐵}{𝑛}𝑓𝑥𝑠:𝖵𝖾𝖼(𝐵,𝑛). The object equations fix ?𝑋,?𝑌,?𝑝, while the strict level equations fix ?ℓ𝐴,?ℓ𝐵. No choice remains.
Exercise 112.12.
The following four constraints are well typed in the indicated metacontexts.
𝟢 ≐𝗌𝗎𝖼(𝟢) :ℕ is a rigid-head clash.
For ?𝛼 :[𝑥 :ℕ ⊢ℕ], ?𝛼[𝑥] ≐𝗌𝗎𝖼(?𝛼[𝑥]) :ℕ triggers the occurs check.
In 𝑥 :ℕ,𝑦 :ℕ, for ?𝛼 :[𝑥 :ℕ ⊢ℕ], ?𝛼[𝑥] ≐𝑦 :ℕ is a scope escape.
For ?𝐹 :[𝑥 :𝑜 ⊢𝑜] in the signature with the sole constant 𝑐 :𝑜, ?𝐹[𝑐] ≐𝑐 :𝑜 is a non-pattern application.
The first has no solution because distinct canonical constructors of ℕ 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 𝗌𝗎𝖼, so no such contextual definition exists. A legal solution of the third must be typed in the telescope 𝑥 :ℕ, but the rigid ambient variable 𝑦 is not in that telescope and substitution cannot remove it. Hence no scoped solution exists.
The fourth has the two solutions ?𝐹 :=[𝑥]𝑥 and ?𝐹 :=[𝑥]𝑐. 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 𝑜 in context 𝑥 :𝑜 is 𝑥, 𝑐, or a residual neutral; after substituting 𝑐, a residual neutral cannot become the rigid canonical form 𝑐. 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 𝐹 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 𝐺,𝑛 ⇓𝜃𝑡 when recursively unfolding node 𝑛, replacing each metavariable leaf by its 𝜃-image, yields the tree term 𝑡. 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 (𝑛,𝑚) with equal rigid labels 𝐹 and child vectors (𝑛1,…,𝑛𝑘) and (𝑚1,…,𝑚𝑘). The graph step unions the classes of 𝑛,𝑚, removes (𝑛,𝑚), and enqueues every (𝑛𝑖,𝑚𝑖). We prove preservation in both directions. If 𝜃 solves the old state, then 𝐹(𝑡1,…,𝑡𝑘)=𝐹(𝑢1,…,𝑢𝑘),𝐺,𝑛𝑖⇓𝜃𝑡𝑖,𝐺,𝑚𝑖⇓𝜃𝑢𝑖. Rigid injectivity gives 𝑡𝑖 =𝑢𝑖 for every 𝑖. Thus every new child pair and the new parent class are satisfied. Conversely, if 𝜃 solves the new state, every 𝑡𝑖 =𝑢𝑖; 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.