Lectures onType Theory
Chapter 57
Chapter 57Optional

Amortized Resource Analysis and Typed Potentials

Prerequisites. Direct starred prerequisites: none. No later core chapter depends on this route.

A polynomial-time characterization says how expensive every representable program can be. It does not say how many cells one invocation of pairs allocates as a function of its input length. For that problem the bound must mention the input, and the proof must follow the program.

Consider attach(x,l)=match l with [][]y::ys(x,y)::attach(x,ys),pairs(l)=match l with [][]x::xsappend(attach(x,xs),pairs(xs)). If a pair cell and a cons cell each cost one unit, then attach(x,l) consumes two units per element. The call pairs(x::xs) also copies the list returned by attach(x,xs). A linear annotation on the original list cannot pay this linear cost once for every suffix. The missing quantity is potential: stored credit indexed by suffix length.

The fixed RAML calculus

The chapter uses the first-order call-by-value language of Hoffmann and Hofmann [HH10]. Expressions are in let normal form: e::=()bnxx1opx2f(x1,,xk)let x=e1 in e2if x then et else ef(x1,x2)match x with (x1,x2)e[]cons(xh,xt)match x with []e0xh::xte1. Here b{true,false}, nZ, and every ground operation has constant cost. Zero-order types and first-order signatures have the forms A::=unitboolintL(A)(A,A),F::=(A1,,Ak)A. A finite context is affine. Its disjoint union Γ1,Γ2 is defined only when the domains are disjoint. Contraction is therefore an explicit sharing rule rather than an implicit property of contexts.

Let H be a finite heap from locations to values and let V be a finite stack from variables to values. The resource judgment V,Hqqev,H means that evaluation starts with qQ0, never makes the counter negative, returns v,H, and leaves qQ0. Its consumption is qq. The relation is terminating big-step evaluation: divergence has no derivation.

The rules are parameterized by constants Kic. The superscript names a construct and the subscript separates the before- and after-costs of a compound rule. This chapter fixes the heap-cell metric Kpair=Kcons=1,Kic=0for every other construct and index. Thus allocation, not evaluation steps or reclaimed space, is counted. The pair and cons rules are V(x1)=v1V(x2)=v2ldom(H)V,Hqq+Kpair(x1,x2)l,H[l(v1,v2)]EPair V(xh)=vhV(xt)=vtldom(H)V,Hqq+Kconscons(xh,xt)l,H[l(vh,vt)]ECons The two compound rules used below are V,Hq2q1K1lete1v1,H1V[xv1],H1q3+K3letq2K2lete2v2,H2V,Hq3q1let x=e1 in e2v2,H2ELet and, when Σ(f)=(A1,,Ak)q/qA, the function body is ef with formal parameters y1f,,ykf, and V(xi)=vi, [y1fv1,,ykfvk],Hu+K2appuK1appefv,HV,Huuf(x1,,xk)v,HEFunApp. Every rule is invariant under adding the same a0 to its two counters. This counter-shift property is needed in the let and function-call cases of soundness.

Exercise 57.1

★☆☆ Prove counter shift for the two allocation rules and a two-premise let rule. State where the inequality a0 is used.

Binomial potential

A list annotation is a nonempty vector p=(p1,,pd)Q0d. Define φ(n,p):=i=1dpi(ni),C(p1,,pd):=(p1+p2,,pd1+pd,pd). The degree d is fixed while constraints are generated. The coefficients are nonnegative in this basis; their expansion in the monomial basis may have negative coefficients.

Lemma 57.1 — Head–tail identity

For every nN and annotation p, φ(n+1,p)=p1+φ(n,C(p)).

Proof of Lemma 57.1 — Head–tail identity

Proof. Pascal’s identity places its reason on the decisive equality: φ(n+1,p)=i=1dpi(n+1i)=Pascali=1dpi(ni)+i=1dpi(ni1)=p1+i=1d1(pi+pi+1)(ni)+pd(nd)=(57.2)p1+φ(n,C(p)). ◻

The resource-annotated types are A::=unitboolintLp(A)(A1,A2). If a heap value v matches A, its potential ΦH(v:A) is defined by ΦH(v:C)=0(C{unit,bool,int}),ΦH((v1,v2):(A1,A2))=ΦH(v1:A1)+ΦH(v2:A2),ΦH(Null:Lp(A))=0,ΦH(l:Lp(A))=p1+ΦH(v:A)+ΦH(l:LC(p)(A)) when H(l)=(v,l). Repeated use of lemma 57.1 gives H(l)=[v1,,vn]ΦH(l:Lp(A))=φ(n,p)+i=1nΦH(vi:A). For a context, ΦV,H(Γ):=xdom(Γ)ΦH(V(x):Γ(x)).

The source also extends the same mechanism to fixed-arity trees. The empty tree has zero potential. For a k-ary node l with payload v and children l1,,lk, ΦH(Null:Tp(A))=0,ΦH(l:Tp(A))=p1+ΦH(v:A)+i=1kΦH(li:TC(p)(A)). This clause defines annotated-tree potential; no theorem in this chapter assumes that tree size is determined solely by height.

Exercise 57.2

★☆☆ Convert 3n+3n2 and 14n+14n2 to nonnegative linear combinations of (n1) and (n2).

Sharing, weakening, and the typing invariant

Write A<:B when the two types have the same shape and A carries at least the potential of B. The list clause is Lp(A)<:Lq(B)A<:B and pq. The sharing relation share(A;A1,A2) splits one value’s potential between two occurrences: share(C;C,C)(C{unit,bool,int}),share(A;A1,A2)p=q+rshare(Lp(A);Lq(A1),Lr(A2)),share(A;A1,A2)share(B;B1,B2)share((A,B);(A1,B1),(A2,B2)).

Lemma 57.2 — Potential splits and weakens

If share(A;A1,A2), then every matching v,H satisfies ΦH(v:A)=ΦH(v:A1)+ΦH(v:A2). If A<:B, then ΦH(v:A)ΦH(v:B).

Proof of Lemma 57.2 — Potential splits and weakens

Proof. Proceed by induction on the displayed sharing or subtype derivation. In the list-sharing case, the payload equality comes from the induction hypothesis, the head coefficient splits because p=q+r, and the tail coefficients split because C is linear. Equation (57.3) then gives the required equality. In the list-subtype case, coefficientwise order implies φ(n,p)φ(n,q); the element-type induction hypothesis gives the remaining summands in (57.4). Ground and product cases follow directly from (57.3). ◻

The annotated signature assigns (A1,,Ak)q/qA to each function. The judgment Σ;Γqqe:A means that input potential plus q pays evaluation while output potential plus q remains. Four rules show where the invariant performs work: p=(p1,,pd)Σ;xh:A,xt:LC(p)(A)0p1+Kconscons(xh,xt):Lp(A)TCons Σ;Γ1pqK1lete1:AΣ;Γ2,x:Aq+K3letpK2lete2:BΣ;Γ1,Γ2qqlet x=e1 in e2:BTLet Σ;Γ,x:A1,y:A2qqe:Bshare(A;A1,A2)Σ;Γ,z:Aqqe[z/x,z/y]:BTShare Σ;Γqqe:Bxdom(Γ)Σ;Γ,x:Aqqe:BTWeak The paper calls the last rule T-Augment; it is the affine weakening rule. The remaining rules used by name below are Σ(f)=(A1,,Ak)q/qAΣ;x1:A1,,xk:AkqK2appq+K1appf(x1,,xk):ATFunApp A typeΣ;0Knil[]:L0(A)TNil Σ;Γ,x:Aqqe:BA0<:AΣ;Γ,x:A0qqe:BTSupertype Σ;Γqqe:BB<:B0Σ;Γqqe:B0TSubtype Σ;Γppe:BqpqpqpΣ;Γqqe:BTRelax. The list match has two premises. The nil branch receives no list potential. The cons branch binds xh:A and xt:LC(p)(A), and its available constant increases by p1. This is the inverse use of T-Cons forced by lemma 57.1.

Exercise 57.3

★★☆ Let p20 denote the coefficient carried by each output-list cell. In the cons branch of pairs, show the split share(L(p2+3,p2+3)(int);L(p2+3,0)(int),L(0,p2+3)(int)). Identify which occurrence pays attach and which pays the recursive call.

Resource soundness

Write HV:Γ when V(x) is a value matching Γ(x) in H for every xdom(Γ).

Theorem 57.3 — Hoffmann–Hofmann soundness

Let Σ be the annotated signature of a RAML program, and let e be an expression. Suppose HV:Γ and some u,uQ0 satisfy V,Huuev,H. If Σ;Γppe:A,rQ0,qΦV,H(Γ)+p+r, then some qQ0 satisfies V,Hqqev,H,qΦH(v:A)+p+r.

Proof of Theorem 57.3 — Hoffmann–Hofmann soundness

Proof. The proof is simultaneous induction on the typing derivation and its fixed terminating evaluation. Strengthen the induction statement by retaining the arbitrary slack r; without this strengthening, the intermediate resource left by a let cannot be passed to its second premise.

Constructors. For T-Cons, the input potential is ΦH(V(xh):A)+ΦH(V(xt):LC(p)(A)). After paying Kcons and p1, equation (57.3) gives exactly the output potential. The pair case uses additivity of product potential and pays Kpair.

List elimination. If the scrutinee is null, the nil premise has the required resource because its potential is zero. If the scrutinee is a cons location, opening (57.3) yields p1, the head potential, and the shifted tail potential. These are precisely the constant and context required by the cons premise. Applying the induction hypothesis to that premise gives the claimed postcondition.

Let. The first evaluation premise and first typing premise give an intermediate counter at least ΦH1(v1:A)+p+ΦV,H(Γ2)+r; disjointness of Γ1 and Γ2 justifies the context split. Use that amount as the precondition for the second induction hypothesis. Its conclusion is the required bound for v,H. Counter shift aligns the concrete intermediate counters without changing consumption.

Function application. Let Σ(f)=(A1,,Ak)p/pA, and let V(xi)=vi. Program well-formedness supplies the body derivation Σ;y1f:A1,,ykf:Akppef:A. From the caller precondition and T-FunApp, remove K1app; the remainder is at least the formal environment’s potential plus p+r. Apply the induction hypothesis to the premise of E-FunApp. It leaves at least output potential plus p+r; restoring K2app gives the caller’s residual annotation pK2app. Counter shift supplies the exact concrete counters if either inequality is strict. Thus this case uses both signature well-formedness and the sign reversal between T-FunApp and E-FunApp.

Sharing and weakening. For T-Share, lemma 57.2 replaces the single potential of z:A by the sum needed for x:A1,y:A2; substitution in the stack and expression preserves the evaluation. For T-Weak, the extra nonnegative potential is added to slack because x is absent from the expression.

Order rules. Input supertype uses the inequality half of lemma 57.2; output subtype uses it in the opposite position. T-Relax uses its two numerical premises qp and qpqp to increase the initial allowance without reducing the promised remainder.

Remaining syntax. Constants, variables, and ground operations apply their corresponding evaluation rule and its fixed K-constants. A conditional selects the typing premise matching V(x). Product elimination opens the two summands in product potential. T-Nil uses zero output potential. These cases exhaust the expression grammar and preserve the same slack r. ◻

The termination premise is substantive: the theorem bounds every terminating evaluation but does not prove that one exists. Nonnegative slack is also substantive; allowing r<0 would weaken the initial premise while retaining the same postcondition. Well-formedness is structural data required to define every potential in the statement.

Exercise 57.4

★★☆ Give a divergent recursive RAML definition for which the theorem has no applicable evaluation premise. Then show that deleting HV:Γ can make ΦV,H(Γ) undefined.

From a derivation to linear constraints

Assign a fresh nonnegative rational variable to every coefficient and every constant annotation in a syntax-directed derivation. T-Cons generates q=p1+1 under (57.1); list matching generates the shift equations; sharing generates coefficientwise addition; subtyping and relaxation generate inequalities. Every constraint is linear because C and sharing are linear in the coefficients.

For pairs, choose output annotation (1) and zero constant annotations p=p=0. At a cons branch, introduce fresh input coefficients a1,a2, split the shifted tail, and impose a1=0,a2=4,C(a1,a2)=(4,4)=(4,0)+(0,4). The first component pays the three allocations per attached element plus the one unit retained in the output; the second is the recursive input. Nil, sharing, and output subtyping add only nonnegativity and coefficientwise-order constraints. Thus the source derivation admits input annotation (0,4). Instantiating theorem 57.3 with r=0 bounds consumption by input potential minus result potential: allocpairs(n)4(n2)(n2)=3(n2). The RAML prototype table prints the safe monomial bound 3n+3n2=6(n2). It is a distinct, looser analyzer output; it does not replace the local bound in (57.7).

The extended report prints a bound for startBreadth, but not its source program: it says that implementation was available on the then-current RAML website. The companion therefore checks a stated reconstruction, not that unavailable implementation. A compact node (a,b,l1,l2) represents one pair of suffix positions: a,b are their heads and l1,l2 their remaining suffixes. Its two child clauses advance the left suffix, or advance both suffixes. Starting from a list of length n, this yields N(n)=1+2++n=n(n+1)/2 visited nodes. A two-list queue stores those nodes; dequeue reverses its input list only when the output list is empty.

The explicit chapter reconstruction charges twelve named constructor sites per visited node, two per reversal, and two at initialization. For n>0 its selected input has R(n)=n reversals, so B(0)=0,B(n)=12N(n)+2R(n)+2=6n2+8n+2. The artifact emits one event carrying one of those site names; this equation counts that trace and is not an inferred RAML typing. The paper’s displayed heap bound is 14n+14n2=28(n1)+28(n2), which dominates B(n) for every n0. This comparison is only between the report’s bound and the reconstruction’s trace; it does not establish that the two programs coincide. The evaluation-step bounds 3+7n+9n2 and 17+45n+45n2 use a different cost assignment and are not oracles for the heap-cell artifact.

RAML 1.5 is an implementation and experiment source, not the theorem proved in theorem 57.3. In particular, the declarative rules do not prove inference completeness, asymptotic tightness, or machine independence.

Chapter seminar

None of these problems is a prerequisite for a later chapter.

Suggested first pass.

Do exercise 57.5 before the implementation problem exercise 57.7.

Exercise 57.5

★★☆ Derive the recurrence for the exact heap allocation of pairs, solve it as 3(n2), and compare it with both bounds in section 57.5.

Exercise 57.6

★★☆ Use height zero for the empty tree and height one for a single node. For a full binary tree of height h, with zero-potential payloads, unfold (57.5) through height two. State the recurrence for general h without claiming that it applies to non-full trees.

Exercise 57.7

★★★ Practical project.aara-heap-trace-checker Implement the fixed heap-cell trace checker in Kappa. For pairs, maintain the invariant that every recorded unit is emitted by one pair or cons constructor in the reconstruction. For startBreadth, maintain the narrower invariant that every event names one site in the explicit accounting schedule preceding (57.8); do not claim correspondence with the unavailable RAML source. For every 0n7, compute the exact traces, verify equivalence of the paper’s monomial bounds with the nonnegative binomial annotations, and check that each trace does not exceed its bound. The fixed call is startBreadth [1;2;3;4;5;6;7]. Acceptance requires n01234567pairs003918304563startBreadth0164280130192266352. Mutate the breadth bound by dropping the linear contribution to 14n+14n2; the n=1 oracle must fail. The checker illustrates the finite trace calculation and inequality in theorem 57.3; it does not prove that theorem or validate a RAML implementation.

Search the book

Type to search the local edition.