Lectures onType Theory
ch:pattern-compilation: ch:pattern-compilation
appendix sectionsolutions

ch:pattern-compilation: ch:pattern-compilation

Exercise 121.1.

After reversing the rows, the matrix is choose(b,n)=suc(0),choose(tt,n)=0. The first row has no blocking pattern. Ordered priority therefore returns its leaf before inspecting the later constructor row. The case tree is simply leaf(1,suc(0)). Its one schematic leaf equation is choose(b,n)suc(0). The two closed Boolean instances follow by substitution; no case split is needed. The first row matches every Boolean, so the later constructor row can never be the least matching row and reaches no leaf.

Exercise 121.2.

Specializing the vector column against vcons(k,a,xs):Vec(A,suc(k)) generates m=suc(k). The restricted unifier takes one solution step, producing [suc(k)/m]. Hence the index position in this branch is forced to be suc(k). Suppose instead that the inaccessible pattern contains the written term k. Validation then asks for the judgmental equality suc(k)k, which does not hold. The useful diagnostic is therefore: “inaccessible term mismatch; forced suc(k), written k.” Treating the comparison as another equation would not rescue it: orienting k=suc(k) reaches the cycle transition of definition 78.9, because the right side contains the variable being solved.

Exercise 121.3.

Row count is not a decreasing measure. A variable row is copied into every positive branch, and a row headed by the selected constructor survives in its matching branch; the branch may consequently contain as many rows as the parent.

For the matrix whose two patterns are vcons(k,a,xs)andz, the measure μ of lemma 121.13 is initially one: only the outer vcons is a constructor node. In the vnil branch the constructor row is deleted and the variable row is copied, so μ=0. In the vcons branch the outer constructor is consumed; its exposed subpatterns k,a,xs and the copied variable pattern contain no constructor or absurd node, so again μ=0. Thus every recursive branch decreases μ strictly even though row count need not decrease. This proves the matrix-recursion part of the relative lemma; its separate hypothesis accounts for termination of each scheduled restricted-unifier call.

Exercise 121.4.

Splitting the input v:Vec(A,m) gives two branches. The vnil branch solves m=0 and reaches the leaf . In the vcons branch the unifier solves m=suc(k), but specialization deletes the sole row. The reported uncovered symbolic pattern is therefore [suc(k)/m,vcons(k,a,xs)/v],a:A,xs:Vec(A,k). It is well typed, but if A:=Id2(tt,ff), the internal no-confusion map of example 30.12 sends any candidate a:A to 0. Thus, under the separately stated consistency assumption that Timpl has no closed term of 0, the symbolic pattern has no closed instance. This argument uses no canonicity theorem, and the coverage theorem itself does not establish that consistency assumption. If A:=1, take k:=0, a:=, and xs:=vnil. Then vcons(0,,vnil):Vec(1,suc(0)) is a closed uncovered input.

Exercise 121.5.

The leftmost tree first splits x. In each resulting branch the second column blocks. Put Tt:=split(y,{tt([tt/y],leaf(1,0)),ff([ff/y],leaf(2,suc(0)))}),Tf:=split(y,{tt([tt/y],leaf(3,suc(suc(0)))),ff([ff/y],leaf(2,suc(0)))}). The complete tree is split(x,{tt([tt/x],Tt),ff([ff/x],Tf)}). Thus the judgmental leaf equations are g(tt,tt)0,g(tt,ff)suc(0),g(ff,tt)suc(suc(0)),g(ff,ff)suc(0). For example, let N(x,y):=¬(Id2(x,tt)×Id2(y,tt))׬Id2(y,ff). Boolean case analysis proves N(x,y)IdN(g(x,y),suc(suc(0))): the premise eliminates the (tt,tt) leaf by its first conjunct and both y=ff leaves by its second, leaving only (ff,tt). In contrast, the unconditional equation g(x,y)=suc(suc(0)) suggested by the third source row is false, for instance at (tt,tt).

Exercise 121.6.

Write the two vector inputs as x:Vec(A,n) and y:Vec(B,n). The complete frontier is A,B,C,f,n,x,y; only x and then y block. Splitting x gives σ0=[0/n,vnil/x],σs=[suc(r)/n,vcons(r,a,as)/x]. In the first branch y:Vec(B,0). The empty-constructor constraint for the second split is (0;y)q:N;Vec(B,q)(0;vnil). Its index component 0=0 is positive because the injectivity transition reduces equal nullary constructor heads to the empty constructor telescope; no reflexive-equation deletion is used. The element component then assigns y:=vnil, giving τ00=[vnil/y]. A vcons(q,b,bs) alternative gives 0=suc(q) and is removed by a conflict certificate.

In the successor branch y:Vec(B,suc(r)). Its empty alternative gives suc(r)=0 and is negative. Its successor alternative gives suc(r)=suc(q); injectivity and solution yield q:=r. Here r is an old frontier variable and q is fresh from the second constructor telescope, so the canonical variable–variable orientation preserves r and eliminates q. The forced-image matcher then consumes the freshly created q-cell: applying q:=r compares its dot .r with the forced image r, discharging rr. This gives τss=[r/q,vcons(r,b,bs)/y]. Put es:=vcons(r,fab,zipWith(A,B,C,f,r,as,bs)). Omitting the two negative branches but retaining their certificates, the typed tree is as follows. Each split is keyed by a constructor name; its declared constructor telescope binds the variables used in that branch. split(x,{vnil(σ0,split(y,{vnil(τ00,leaf(1,vnil))})),vcons(σs,split(y,{vcons(τss,leaf(2,es))}))}). Its judgmental leaf equations are the two written source clauses: zipWith(A,B,C,f,0,vnil,vnil)vnil,zipWith(A,B,C,f,suc(r),vcons(r,a,as),vcons(r,b,bs))es. All seven original telescope positions are therefore present in both leaf instances. The target has the type displayed in the exercise. The recursive call uses as, the direct child of the designated first vector; bs is the corresponding second-vector child but is not the termination witness.

Exercise 121.7.

Put D(x):=IdA(a,x). Splitting e:D(a) against reflexivity generates the homogeneous telescopic equality (a;e)x:A;D(x)(a;refla). Unfolding one telescope layer first presents the index component a=a:A; only after solving it could the dependent tail compare the transported e with refla. The neutral equation a=a has neither a permitted solution step, since neither side is a unification variable, nor a permitted injectivity or conflict step. Deletion is outside the restricted unifier. The complete run is consequently the zero-step run ending at that same unsolved index component. In particular, it never reaches an assignment e:=refla. Compilation reports stuck unification.

Replacing the reflexivity pattern by ! asks the compiler to certify that no constructor is compatible. But refla:D(a) is a compatible constructor instance. Its full telescopic constraint is the one displayed above; the stuck neutral component is not a conflict certificate, so the absurd assertion is invalid.

Exercise 121.8.

The seven first results are as follows.

  1. Complete Boolean negation succeeds: the tt and ff constraints are positive, and each specialized matrix has a leaf.

  2. The sole tt clause reports uncovered constructor ff. Its certificate is the positive path choosing ff together with the resulting empty specialized matrix.

  3. The identity-family K clause reports stuck unification at the first component a=a of (a;e)x:A;D(x)(a;refla).

  4. Append with .k reports an unforced inaccessible term. The positive vector constraint forces suc(k), whereas the row wrote k; the failed check is suc(k)k.

  5. The declaration h(!) at 2 reports a reachable absurd pattern. Boolean constructors are enumerated in declaration order, so the first result is badAbsurd(1,tt,(tt)). The ff branch is positive as well, so no negative certificate required by ! exists. The practical corpus’s two-constructor list is an aggregate observation, not the mathematical compiler’s single first diagnostic.

  6. The constructor pattern in E’s erased Boolean column is blocking, but that column is not a runtime split position. Compilation returns badRelevance(1,b), where b names the erased binder.

  7. For F, the first row initially selects the reflexivity column. Its positive unifier orients the old-variable equation as a:=x. The second row’s constructor cell tt at a is therefore paired with the neutral forced image x, so the matcher suspends ttforcedByx. The first row next selects its final tt cell. In the ff branch that row is deleted, the second row becomes first, and retrying the suspended task returns stuckForce(2,a,tt,x).

The coverage item reports a constructor path rather than a unifier certificate. The remaining failures expose, respectively, the unsolved equation, the forced-versus-written pair, the reachable constructors, the erased blocker, and the neutral forced image with its demanded head.

Search the book

Type to search the local edition.