• No results found

2.2 Automatic Amortized Analysis

3.3.1 Big-Step Operational Semantics

In the following, I define a big-step operational semantics that measures the quantitative resource consumption of programs. It is parametric in the resource of interest and can measure every quantity whose usage in a single evaluation step can be bounded by a constant. The actual constants for a step on a specific system architecture can be derived by analyzing the translation of the step in the compiler implementation for that architecture [JLH+09].

The semantics is formulated with respect to a stack and a heap as usual: LetLoc

be an infinite set oflocationsmodeling memory addresses on a heap. The set of RAML

values Valis given by

v::=`|b|n|NULL|(v1,v2)

A valuevValis either a location`Loc, a boolean constantb, an integern, a null value NULL or a pair of values (v1,v2). I identify the tuple (v1, . . . ,vn) with the pair (v1, (v2,· · ·)· · ·).

Aheapis a finite partial mappingH:LocValthat maps locations to values. A

stackis a finite partial mappingV: VID→Valfrom variable identifiers to values. Since we also consider resources like memory that can become available during an evaluation, we have to track thewatermarkof the resource usage, that is, the maximal number of resource units that are simultaneously used during an evaluation. To derive a watermark of a sequence of evaluations from the watermarks of the sub evaluations, you have also to take into account the number of resource units that are available after each sub evaluation.

The operational evaluation rules in Figures 3.2 and 3.3 thus define an evaluation judgment of the form

V,H`e v,H0|(q,q0)

expressing the following. If the stackV and the initial heap H are given then the expressioneevaluates to the valuevand the new heapH0. In order to evaluateeone needs at leastq∈Q+resource units and after the evaluation there are at leastq0∈Q+ resource units available. The actual resource consumption is then δ=qq0. The quantityδis negative if resources become available during the execution ofe.

In contrast to similar versions in earlier works there is at most one pair (q,q0) such thatV,H `e v,H0|(q,q0) for a given expressione, a heapH and a stackV. The non-negative numberqis the watermark of resources that are used simultaneously during the evaluation.

It is handy to view the pairs (q,q0) in the evaluation judgments as elements of a monoid1Q=(Q+0×Q+0,·). The neutral element is (0, 0) which means that resources are neither used nor restituted. The operation (q,q0)·(p,p0) defines how to account for an evaluation consisting of evaluations whose resource consumptions are defined by (q,q0) and (p,p0), respectively. We define

(q,q0)·(p,p0)=

½

(q+pq0, p0) ifq0≤p

(q, p0+q0p) ifq0>p

The intuition is that you needqresource units to perform the first evaluation and after the evaluationq0restituted units remain. Now you have to pay for the second operation which needspunits. Ifq0≤pthen you additionally needpq0resources to pay for both evaluations and havep0 resources left in the end. Ifq0>pthenq units suffice 1In fact, it is possible to define the evaluation more abstractly with respect to an arbitrary monoidM.

x∈dom(V)

V,H`x V(x),H|Kvar(E:VAR) V,H`() NULL,H|Kunit (E:CONSTU)

n∈Z

V,H`n n,H|Kint (E:CONSTI)

b∈{True,False}

V,H`b b,H|Kbool (E:CONSTB)

V(x)=v0 [yf 7→v0],H`ef v,H0|(q,q0)

V,H`f(x) v,H0|K1app·(q,q0)·K2app (E:APP)

x1,x2∈dom(V) v=op(V(x1),V(x2))

V,H`x1op x2 v,H|Kop

(E:BINOP)

V(x)=True V,H`et v,H0|(q,q0)

V,H`ifxthenetelseef v,H0|K1conT·(q,q0)·K2conT

(E:CONDT )

V(x)=False V,H`ef v,H0|(q,q0)

V,H`ifxthenetelseef v,H0|K1conF·(q,q0)·K2conF

(E:CONDF) V,H`e1 v1,H1|(q,q0) V[x7→v1],H1`e2 v2,H2|(p,p0) V,H`letx=e1ine2 v2,H2|K1let·(q,q0)·K let 2 ·(p,p0)·K let 3 (E:LET) x1,x2∈dom(V) v=(V(x1),V(x2)) V,H`(x1,x2) v,H|Kpair (E:PAIR) V(x)=(v1,v2) V[x17→v1,x27→v2],H`e v,H0|(q,q0)

V,H`matchxwith(x1,x2)→e v,H0|K1matP·(q,q0)·K2matP (E:MATP)

V,H`nil NULL,H|Knil (E:NIL)

xh,xt∈dom(V) v=(V(xh),V(xt)) `6∈dom(H)

V,H`cons(xh,xt) `,H[`7→v]|Kcons

(E:CONS)

V(x)=NULL V,H`e1 v,H0|(q,q0)

V,H`matchxwith|nil→e1|cons(xh,xt)→e2

v,H0|K1matN·(q,q0)·K2matN

(E:MATNIL)

V(x)=` H(`)=(vh,vt) V[xh7→vh,xt7→vt],H`e2 v,H0|(q,q0)

V,H`matchxwith|nil→e1|cons(xh,xt)→e2

v,H0|K1matC·(q,q0)·K2matC

(E:MATCONS)

V,H`leaf NULL,H|Kleaf (E:LEAF)

x0,x1,x2∈dom(V) v=(V(x0),V(x1),V(x2)) `6∈dom(H)

V,H`node(x0,x1,x2) `,H[`7→v]|Knode (E:NODE)

V(x)=NULL V,H`e1 v,H0|(q,q0)

V,H`matchxwith|leaf→e1|node(x0,x1,x2)→e2

v,H0|K1matTL·(q,q0)·K2matTL

(E:MATLEAF)

V(x)=`

H(`)=(v0,v1,v2) V[x07→v0,x17→v1,x27→v2],H`e2 v,H0|(q,q0)

V,H`matchxwith|leaf→e1|node(x0,x1,x2)→e2

v,H0|K1matTN·(q,q0)·K2matTN

(E:MATNODE)

to perform both evaluations. Additionally, theq0−punits that are not needed for the second evaluation are added to the resources becoming finally available.

The following facts are often used in proofs.

Proposition 3.3.1 Let (q,q0)=(r,r0)·(s,s0). 1. qr and qq0=rr0+ss0

2. If (p,p0)=( ¯r,r0)·(s,s0) and ¯rr thenpqandp0=q0

3. If (p,p0)=(r,r0)·( ¯s,s0) and ¯ssthenpqandp0≤q0

4. (r,r0)·((s,s0)·(t,t0))=((r,r0)·(s,s0))·(t,t0)

If resources are never restituted (as with time) then we can restrict ourselves to elements of the form (q, 0) and (q, 0)·(p, 0) is just (q+p, 0).

I identify (positive and negative) rational numbers with elements ofQas follows:

q≥0 denotes (q, 0) andq<0 denotes (0,−q). This notation avoids case distinctions in the evaluation rules since the constantsKthat appear in the rules can be negative. Then resources are restituted during an evaluation step. This is the case for stack space and also for heap space in a destructive pattern match which is omitted here for simplicity. The evaluation rules are standard apart from the resource information that measure the resource consumption. These resource annotations are very similar in each rule and I explain them for the rules E:VARand E:CONDT.

Assume that the resource cost for looking up the value of a variable on the stack and copying it to some register isKvar≥0. The rule E:VARthen states that the resource consumption of the evaluation of a variable is (Kvar, 0). So the watermark of the resource consumption isKvarand there are no resources left after the evaluation. IfKvar<0 then E:VARstates that the resource consumption of the evaluation of a variable is (0,−Kvar). So the watermark is zero and after the evaluation there areKvarresources available.

Now consider the rule E:CONDT. Assume that the resource cost of looking up

the value of the variable x and jumping to the source code ofet isK1conT≥0. As- sume furthermore that the jump back to the code after the conditional costsK2conT≥ 0 resources. Then the rule E:CONDT states that the cost for the evaluation of are

(K1conT, 0)·(q,q0)·(K2conT, 0) if the watermark for the evaluation ofet isq and if there areq0resources left after the evaluation. There are two cases. Ifq0≥K2conTthen the overall watermark of the evaluation isq+K1conTand there areq0−K2conTresources avail- able after the evaluation. Ifq0<KconT

2 then the overall watermark of the evaluation is q+K1conT+K2conT−q0and there are zero resources available after the evaluation. The statement is similar for negative constantsKiconT.

The values of the constantsKix∈Qin the rules depend on the resource, the imple- mentation and the system architecture. In fact, the value of a constant can also be a function of the type of a subexpression. For instance, the size of a cons cell depends on the size of the value that is stored in the cell in our implementation. Since the types of all subexpressions are available at compile time, this is a straightforward extension.

v∈{True,False}

HÍv7→v:bool( V:BOOL)

v∈N

HÍv7→v:int( V:INT)

v=NULL

HÍv7→() :unit( V:UNIT)

v=(v1,v2) HÍv17→a1:A1 HÍv27→a2:A2 HÍv7→(a1,a2) : (A1,A2) ( V:PAIR) v=NULL A∈A HÍv7→[] :L(A) ( V:NIL) v=NULL A∈A HÍv7→leaf:T(A) ( V:LEAF) vLoc H(v)=(v1,v2) H0=H\v Hv17→a1:A Hv27→[a2, . . . ,an] :L(A) HÍv7→[a1, . . . ,an] :L(A) ( V:CONS) vLoc H(v)=(v0,v1,v2) H0=H\v Hv07→a:A Hv17→t1:T(A) Hv27→t2:T(A) HÍv7→tree(a,t1,t2) :T(A) ( V:NODE)

Figure 3.4: Relating heap cells to semantic values.

Actual constants for stack-space, heap-space and clock-cycle consumption were determined for the abstract machine of the language Hume [HM03] for the Renesas M32C/85U architecture. A list can be found in the literature [JLH+09].

The following proposition states that heap cells are never changed during an evalua- tion after they have been allocated. This is a convenient property to simplify some of the later proofs but it is not necessarily needed. We would not have this property if we would include an destructive pattern matching in RAML. How to formally deal with it is described in the literature [JLH+09].

Proposition 3.3.2 Letebe an expression,V be a stack, andHbe a heap. IfV,H`e v,H0|(q,q0) thenH0(`)=H(`) for all`∈dom(H).

PROOF The only rules that allocate new heap cells are E:CONSand E:NODE. And in these rules we have the side condition`6∈Hthat prevents an old location from being

changed by assigning a value to`. ■