Lectures onType Theory
ch:refinement-types: ch:refinement-types
appendix sectionsolutions

ch:refinement-types: ch:refinement-types

Exercise 10.1.

First prove the requested commutation lemma by induction on e1: ()e1[a/x]ye2=(e1ye2)[a/x]. All binders are alpha-renamed fresh for a,e2,x,y. If e1=b is an atom, the two sides are e2[b[a/x]/y] and e2[b/y][a/x]; ordinary capture-avoiding substitution commutes because xy, yfv(a), and xfv(e2). For e1=let z=c in e, both sides retain the same fresh head let and () for e identifies their tails. The conditional clause distributes bind composition into both branches, so the two branch induction hypotheses prove (). For e1=error, both sides are error.

Now induct on e0. If e0=a is an atom, the desired equation is exactly (): (e1[a/x])ye2=(e1ye2)[a/x]. If e0=let z=c in e, alpha-rename z fresh. Both sides retain let z=c in(), and the induction hypothesis for e equates the two tails. If e0 is a conditional, expanding the definition on both sides gives conditionals with the same test; apply the induction hypothesis separately to the then and else branches. Finally, (errorxe1)ye2=error=errorx(e1ye2). These are all expression forms, so associativity holds modulo exactly the capture-avoiding renamings stipulated by the definition.

exercise 10.2.

Both (a) and (b) are well formed. In (a), the domain adds La to the scope and the codomain binder adds ν, so νLa1 passes WF-Base. In (b), the domain adds i and the array codomain binder contributes Lν, so Lνi0 is likewise scoped.

Expression (c) is rejected. A function-shaped declaration contributes no predicate vertex, so f is absent from V(f:(intint)); the occurrence of f in νf0 fails the premise of WF-Base. Expression (d) is well formed in the empty context: Lν is the distinguished vertex supplied by the array refinement binder itself, and 0 is always available.

exercise 10.3.

The graph edges, written in the order of the hypotheses, are y2x,z4y,x1z. Their identifiers form the adjacent cycle yxzy. The replay checker verifies the common endpoints and calculates 2+1+(4)=1<0. Thus this three-edge list is a contradiction certificate.

After replacing the last constant by 2, take h(0)=0,h(x)=0,h(z)=2,h(y)=2. Then h(x)h(y)=2, h(y)h(z)=4, and h(z)h(x)=2. All three constraints hold, so the zero-weight cycle is not a contradiction.

exercise 10.4.

Introduce the fresh vertex z for the source refinement. Its upper-bound atom contributes the edge La1z. The target asks for zLa0, and that one-edge path has weight 10. Hence S-Base gives the displayed subtype judgment. The source’s lower-bound edge z00 is present but is not needed for this goal.

For the reverse direction, let a be a one-element array and assign z=1. Then zLa=0, so the weaker target refinement is satisfied. But the putative reverse target contains zLa1, namely 01, which is false. This valuation refutes the entailment premise of the reverse S-Base instance.

exercise 10.5.

Without the nonempty input refinement, exact length and shift synthesis still give n=La and i=n1. Therefore the upper-bound goal has the path La0n1i, of weight 1, which certifies iLa1.

The lower-bound goal is 0i0. Its available route is i1n0La00, whose weight is 1, not at most 0. This failure is genuine: set h(0)=0,h(La)=h(n)=0,h(i)=1. The potential satisfies both equalities n=La, i=n1, and the implicit length constraint, but it makes h(0)h(i)=1>0. Hence no certificate for the lower bound exists.

exercise 10.6.

Write F=fix f(x).e1:x:st. Inversion before the E-Fix step supplies f:(x:st),x:se1t,vs,y:t[v/x]e2u, with yfv(u). Rule D-Fix, followed by reflexive subtyping and D-Sub, gives Fx:st. Substitution for the function variable is therefore x:se1[F/f]t; the types do not change because a function-shaped f supplies no predicate vertex. Substitution for the argument is then e1[F/f,v/x]t[v/x]. Finally lemma 10.22, with the displayed continuation premise, gives e1[F/f,v/x]ye2u, which is exactly the reduct’s required type.

exercise 10.7.

With only 0ν0, the candidate invariant says i0 and contains no relation between i and La. Take La=1, i=2, and j=1. The else guard is satisfied, the shift equation j=i1 holds, and j0. The read’s upper VC is nevertheless jLa1,that is01, so the assignment is rejected.

Now add νLa1. At entry, n=La satisfies both n0 and nLa1. In the recursive branch, the guard gives i1, hence j=i10, while iLa1 gives jLa01. Thus the recursive call preserves both qualifiers. The same valuation La=1,i=2,j=1 satisfies them, but still makes j=La and falsifies the strict read bound. The nearby qualifier is inductive but too weak for array safety.

exercise 10.8.

For A=7, E-Len first yields E=let z=getA1 in z. The bounds conjunction is 01 followed by 1<1. Guard elaboration therefore produces if 01 then(if 1<1 then E elseerror) elseerror. The first test is true, so E-IfT selects the inner conditional. The second test is false, so E-IfF yields error. The failing test is the strict upper bound i<len(A); evaluation never reaches the stuck get.

Exercise 10.9.

The consumer does not compare the producer’s certificates with the producer’s claimed VC list. At protocol step 2 it reruns the deterministic generator on lastt, producing the complete list C, including the bounds VC for the get. At step 3 it matches the supplied bundle Π against this recomputed list. Because Π has no certificate for the recomputed get VC, matching or replay fails and evaluation is never enabled at step 4.

If the consumer instead accepted a producer-supplied VC list, the malicious producer could delete precisely the obligations that make an unsafe term untypable and then provide valid certificates for the harmless remainder. Acceptance would no longer imply that every VC generated by the fixed checker is valid. Therefore checker correctness could not yield et, and preservation/progress could not be invoked. The first implication of theorem 10.32 would be false; VC recomputation is the step that binds the evidence to the actual program and policy.

Exercise 10.10.

In the empty context the only nonconstant vertex available to a refinement is ν. After normalization, every atom is one of νk,kν,a constant truth value, for some kZ. A finite conjunction collects finitely many upper and lower bounds. If a constant conjunct is false, its denotation is empty. Otherwise, taking the least upper bound U and greatest lower bound L that occur, its denotation is one of Z,{nnU},{nLn},{nLnU},. Every nonempty unbounded case contains consecutive integers and hence an odd integer. Every bounded interval is finite, whereas the set of even integers is infinite in both directions. The empty case and all of Z are also plainly wrong. Thus no predicate in this conjunction-only difference fragment denotes exactly the even integers.

Search the book

Type to search the local edition.