Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Jones N.D.Partial evaluation and automatic program generation.1999

.pdf
Скачиваний:
9
Добавлен:
23.08.2013
Размер:
1.75 Mб
Скачать

Binding-time analysis ensuring termination 301

Since a variable can only have its value decreased nitely many times, we get a bound on the number of iterations in a loop where a static variable is decreased at every iteration. As seen in the rst part of Example 14.1, this can bound the number of times other variables can be increased in that loop.

The nite downwards closure property is crucial for this reasoning, which means that our methods do not work for, say, integer types. Therefore we assume all numerals in the rest of this chapter to be natural numbers.

14.3Binding-time analysis ensuring termination

In this section we develop a new algorithm that yields a congruent and always nite division, in contrast to that of Section 4.4.6. Variables will be classi ed in one of three categories: static, meaning that it is guaranteed to assume only nitely many values, and can be computed at partial evaluation time (congruence); or dubious, meaning that it is not dependent on dynamic variables, but is not (yet) known to be of bounded static variation; or dynamic.

(Note that previous chapters have taken a more relaxed attitude towards the term `static'.) Our de nition does not mean that a static variable cannot grow, only that all variation must be bounded for any static program input.

To ensure niteness it may be necessary to reclassify some dubious variables as dynamic, and this may lead to yet more reclassi cations to re-establish congruence. For example, a variable is dubious if it is increased inside a loop. If a bounded static variable is properly decreased in the same loop, then its growth is limited; if not, it must be classi ed as dynamic.

Below we present an analysis that collects information about dependencies and size relations among variables in a program. From the result of this analysis, a division ensuring termination will be found roughly in the following manner:

1.Classify all variables that depend on dynamic input variables as dynamic. Classify all non-dynamic variables as dubious.

2.A dubious variable x that only depends on itself and on static variables is reclassi ed as static if

whenever x is increased in a loop, some static variable is decreased. (Special case: x is never increased in a loop.)

3.When step 2 is no longer applicable, reclassify remaining dubious variables as dynamic.

seq1; seq2

302Termination of Partial Evaluation

14.3.1Important concepts

Syntax and semantics

Recall that a ow chart program with input variables x1 . . . xk consists of a read statement read x1 . . . xk; followed by a sequence of labelled basic blocks: l0:bb0 l1:bb1 . . . ln:bbn . If the program has variables x1, . . . , xm (m k) then a store v is represented by an m-tuple of values v = (v1, . . . , vm). Below we shall use the mathematical semantics for ow chart programs shown in Section 3.3.3.

Dependency

Variable x depends on variable y over the one-assignment sequence x := e if y occurs in e. Further, x depends on y over sequence if one of the following conditions holds:

1.z depends on y over seq1 and x depends on z over seq2;

2.x depends on y over seq1 and x is not assigned in seq2.

Variable x depends on variable y along a path of labels l1, l2, . . . , li in the ow chart i x depends on y over the concatenation of the assignments at l1, . . . .

Loops

A loop is a sequence of labels l1, l2 , . . . , li where l1 = li . Note that we do not disallow lj = l1 for 1 j i. A variable y is increased in a loop when y depends on y along the loop and its value grows for each iteration. Similarly, x is decreased in a loop if x depends on x along the loop and its value diminishes for each iteration. In Example 14.1, y is increased and x is decreased in the loop.

Example 14.2 Consider the following program fragment:

a:x := x-1; y := y+2;

if e1 goto a else b;

b:x := x+2; y := y-1;

if e2 goto a else b;

x is decreased and y is increased in the loop a, a. Note that both variables are increased in the loop a, b, a. Both variables should be classi ed as dynamic no

matter what the rest of program looks like.

2

14.3.2Size and dependency analysis

In this section we analyse the dependencies and size variances among the program variables x1 . . . xm along various program control paths ppi, ppi+1, . . . , ppj in the

Binding-time analysis ensuring termination 303

ow chart. A ow description is of form (ppi,ppj ) : (d1, . . . , dm). Each dk describes the dependency of the value of variable xk at the end of the path on the variables x1 . . . xmat the beginning of the path.

Variable descriptions

A variable description has one of three forms: d = I(V ), d = E(V ), or d = D(V ), where V VarIndex = f1; . . . ; mg. VDesc is the set of all variable descriptions.

When a variable xi is described by d, then it depends on those variables xj for which j 2 V . The letter I, E, or D describes the relation between the size of xi and the xj 's: D denotes strictly Decreasing, E denotes non-increasing = less than or Equal, and I denotes (possibly) Increasing. Also, when a value is both increased and decreased we classify it as increasing.

Given a ow description of form (ppi,ppj):d, the table below summarizes how to interpret the elements of d(recall that v#k selects the k'th component of v):

dk = D(V )

means

 

j #k <

 

 

i#s,

for all s 2 V

v

v

dk = E(V )

means

 

j #k

 

i#s,

for all s 2 V

v

v

dk = I(V )

means

 

j #k depends on

 

i#s,

for all s 2 V

v

v

We take ?(V ) to mean either I(V ), E(V ), or D(V ). Note the special case V = fg. This implies that xi depends on no variables and thus is constant. Any description ?(fg) would correctly describe the e ect of an assignment of constant value such as xi := 42.

Flow descriptions

Associate with any two program points, ppi and ppj, a description of the variables to get a ow description of form (ppi, ppj) : d, where d = (d1 , . . . , dm). The type of a ow description is thus PPoint PPoint Vdescm . A ow description of this form means that in one possible computation

(ppi, vi) ! . . . ! (ppj, vj)

the dependency of vj on vi is described by (d1, . . . , dm). Note that we also include computations that do not start at the initial program point.

14.3.3Flow description of all possible computations

We shall now de ne a set of ow descriptions FD: }(PPoint PPoint Vdescm) that captures all possible computations. FD will be a set of triples (ppi, ppj) : d, where d describes the dependency relations between program variables at the end of one possible path from ppi to ppj, and the variables' values at the start of that same path.

Note that FD is nite since there are only nitely many di erent triples (even though there are in nitely many paths). We approximate the control function ci

304 Termination of Partial Evaluation

by aci (independent of the store), de ned by:

aci

= flj, lkg

if bbi = . . . ; if e

then goto lj else goto lk

aci

=

fljg

if bbi = . . . ; goto

lj

aci

=

fg

if bbi = . . . ; return e

and de ne FD inductively by the following two rules:

1. For all program points ppi, (ppi,ppi) : (E(f1g), . . . , E(fmg)) 2 FD

2. If (ppi,ppj ) : d 2 FD, ppq 2 acj, and d0 = BlockDesc[[bbj ]d then (ppi,ppq) : d0 2 FD.

The function BlockDesc which is de ned below computes the e ect of a basic block on a store description d.

BlockDesc[[a1; . . . ; an ]]d = (AsgDesc[an]] . . . AsgDesc[[a1]]) d

AsgDesc[[xk := e]] d = (d1, . . . , dk,1, ExpDesc[[e]]d, dk+1, . . . , dm)

 

 

 

 

 

 

 

 

 

 

where

d

= (d1, . . ., dm)

ExpDesc[[e1 + e2]]

 

 

 

 

= I(V 1 [ V 2)

d

 

 

 

 

 

 

 

 

 

 

 

 

where ?(V 1) = ExpDesc[[e1]]

 

 

 

 

 

 

 

 

 

d

 

 

 

 

 

 

 

 

 

 

 

?(V 2) = ExpDesc[[e2]]d

ExpDesc[[sub1 e]]

 

 

 

 

= decrease(ExpDesc[[e]]d)

d

ExpDesc[[cons e1 e2]]

 

= ExpDesc[[e1 + e2]]d

d

ExpDesc[[hd e]]

 

 

 

 

= ExpDesc[[sub1 e]]d

d

 

 

ExpDesc[[xp]]

 

 

 

 

= d#p

d

 

 

ExpDesc[[<constant>]]d = ?(fg) (choice of I, E, or D immaterial) d I(V ) E(V ) D(V )

decrease(d) I(V ) D(V ) D(V )

The cons case is typical of increasing functions, and the hd case is typical of decreasing functions.

14.3.4Binding-time analysis algorithm

Let a program with basic blocks pp0:bbpp0 pp1:bbpp1 . . . ppn:bbppn be given. Input variables are x1 . . . xk of which x1 . . . xs , s k, are dubious. (We carefully

avoid the word static until the boundedness has been shown.) The algorithm below computes a division that guarantees termination of partial evaluation.

1.Compute FD as described in the previous section.

2.Classify as dynamic xs+1 . . . xk as well as all variables xj for which there exist q 2 f0; . . . ; ng and i 2 fs + 1; . . . ; kg such that

Safety of BTA algorithm 305 (pp0,ppq):(d1, . . . , dj,1, ?(V ), dj+1, . . . , dm) 2 FD, i 2 S

3.Classify all yet unclassi ed variables as dubious.

4.Reclassify as static, any set W of dubious variables ful lling both of the following conditions:

(a)8xj 2 W , 8 (ppp,ppq ):(d1, . . . , dj,1, ?(V ), dj+1, . . . , dm) 2 FD,

8i 2 V :

xi dubious implies xi 2 W

(b) 9g 2 f1; . . . ; mg, such that:1

8 (ppq ,ppq ):(d1, . . . , dj,1, I(V ), dj+1, . . . , dm) 2 FD:

(j 2 V and xj 2 W ) implies (xg is static and dg = D(T ) and g 2 T )

5.When step 4 can no longer be used to reclassify dubious variables as static, reclassify remaining dubious variables as dynamic.

Note that step 4 can reclassify a set of dubious variables at a time. This is useful when dubious variables are mutually dependent and cannot be reclassi ed `one at

atime'.

14.4Safety of BTA algorithm

What needs to be proven about the above algorithm is that an application of step 4 does not classify any variable that can assume in nitely many values as static. Assume that the division obtained by reclassifying all dubious variables as dynamic guarantees niteness of poly and prove that one application of step 4 does not destroy this property.

Suppose the algorithm classi es x1 . . . xs as static and xs+1 . . . xm as dynamic. Let divs: Valuem ! Values be the function that selects the static part vs of a store v. De ne (ppi, vsi) ) (ppj, vsj) to hold, i

1.ppj 2 aci

2.9 v: vsi = divs(v), vsj = divs(wi(v))

The relation ) approximates the notion of being a `successor' as de ned in Chapter 4 since both branches are followed for static conditionals. Let a program and static input vs0 be given. We shall demonstrate the niteness of poly by showing the following superset to be nite:

1See Exercise 14.8 for a generalization of this step.

306 Termination of Partial Evaluation f(pp, vs) j (pp0, vs0) ) (pp, vs)g

where (pp0, vs0) is the initial specialized program point.

The proof is by contradiction, so assume conversely that f(pp, vs) j (pp0, vs0) ) (pp, vs)g is in nite. Then there must exist an in nite chain where all (ppi, vsi) are di erent:2

(pp0, vs0) ) (pp1, vs1) ) . . .

We shall refer to this in nite chain as ( ).

A dependency chain is a sequence of pairs of natural numbers (i1; k1) >(i2; k2 ) >

.. . satisfying:

1.(ppi1 , vsi1 ) )+ (ppi2 , vsi2 ) )+ . . .

2.For j = 1; 2; . . .:

(ppij ,ppij+1 ):d 2 FD, d = (d1, . . . , dkj+1,1, I(V ), dkj+1+1, . . . , dm), kj 2

V

In the de nition of dependency chains the is are indexes into ( ). For each j, xkj+1 depends on and is larger than xkj . Observe that any subchain of a dependency chain is itself a dependency chain.

There are arbitrarily long dependency chains. Justi cation: suppose they had a maximum length K. Variables are assigned constant values a nite number of places (initial binding of input variables and (possibly) assignments to constant expressions). Also, a nite number of store transformations are de ned by the basic blocks. By the nite downwards closure property of the value domains, applying at most K consecutive increasing store transformations can only lead to a nite number of di erent values.3

From the existence of arbitrarily long dependency chains, we may conclude the existence of arbitrarily long self-dependency chains of form (i1; k) > (i2; k) > . . .

with ppi1 = ppi2 = . . . , as there are only nitely many di erent program points and variables. For a two-element self-dependency chain (i1; k) > (i2; k) we have (by the de nition of dependency chains) an element in FD of form (ppi,ppi):d, where d = (d1, . . ., dk,1, I(V ), dk+1, . . . , dm), k 2 V , and for such k step 4b in the BTA provides a g such that dg = D(T ), g 2 T , xg static.

This fact yields arbitrarily long chains

vsi1 #g > vsi2 #g > . . .

of unbounded length which contradicts the nite downwards closure property and concludes the proof.

2Not hard to show (K•onig's Lemma).

3See Exercise 14.6.

Exercises 307

14.5Exercises

Exercise 14.1

Execute the binding-time analysis algorithm of Section 14.3.4 on the

programs in Example 14.1 and 14.2.

2

Exercise 14.2

In Section 4.4.5 it is claimed that there is no computable BTA that

always guarantees termination and never generalizes unnecessarily. Prove this by reduction from the halting problem. Show that lifting any one of the two

requirements renders the problem computable.

2

Exercise 14.3 Consider the mix equation (De nition 4.2). Assuming mix is the partial evaluator described in Chapter 4, does there exist a program for which the

left hand side loops and the right hand side terminates?

2

Exercise 14.4 Prove that the 91 function and Ackermann's function terminate for any input. The 91 function:

 

 

x , 10

if x > 100

 

f(x) = ( f(f(x + 11))

otherwise

Ackermann's function:

8

 

 

 

n + 1

if m = 0

 

>

ack(m; n) =

ack(m , 1; 1)

if m =6 0 ^ n = 0

 

< ack(m , 1; ack(m; n , 1)) if m =6 0 ^ n =6 0

 

>

 

2

 

:

 

Exercise 14.5

Construct a program and a nite division such that reclassifying a

static variable as dynamic renders poly in nite.

2

Exercise 14.6

Find a program and a division such that poly is in nite but no there

is no in nite dependency chain.

2

Exercise 14.7 Let B1 and B2 be divisions, let B1t B2 be the division that classi es variable xi as static if and only if xi is static by both B1 and B2, and let B1u B2 be the division that classi es xi as static if xi is static by at least one of B1 and B2 . Assume that both B1 and B2 are congruent and nite.

1.Is B1u B2 congruent? Is it nite?

2.Is B1t B2 congruent? Is it nite?

2

308 Termination of Partial Evaluation

Exercise 14.8 In the BTA algorithm, step 4b can be relaxed to:

8 (ppq,ppq):d 2 FD, d = (d1, . . . , dj,1, I(V ), dj+1, . . . , dm), j 2 V implies 9g 2 f1; . . . ; mg : dg = D(T ); g 2 T , xg static

1.Find programs for which the relaxed algorithm produces a di erent result than the original algorithm.

2.Prove that the relaxed algorithm is still safe.

2

Chapter 15

Program Analysis

The purpose of automatic program analysis is to obtain some information about the execution of a program without actually executing it, and without using its input. Typical examples of such information are: `the value of variable y will always be an even integer' and `the value of variable g will never be the lambda abstraction x`.e'. The information must be valid for all possible executions of the program.

This chapter explains the program analysis methodology called abstract interpretation, and discusses some program analyses relevant to partial evaluation: the binding-time analysis for Scheme0 programs (Section 5.2) is revisited, and a closure analysis for higher-order languages is presented. We show how to combine these analyses to obtain a binding-time analysis for the higher-order language Scheme1. Finally, we present Launchbury's projection-based binding-time analysis of partially static structures.

15.1Abstract interpretation

Consider an arithmetic expression such as 8 + 3 and suppose we want to know whether its result is even or odd. We may evaluate it concretely, obtaining the concrete number 11, which is odd. However, we may also abstract the values 8 and 3 by their parity (that is, even and odd), and consider instead the problem even + odd. This may be evaluated abstractly, giving the abstract result odd.

Clearly, one could consider other abstractions instead to obtain di erent information about the expression, such as its sign. For this we would abstractly evaluate positive + positive yielding positive.

The important observation is that we have abstract versions of the values (such as 8) as well as of the operations on them (such as `+'). The following tables de ne abstract addition and multiplication on feven; oddg:

309

310 Program Analysis

+

even

odd

 

 

even

odd

 

 

 

 

 

 

 

even

even

odd

 

even

even

even

odd

odd

even

 

odd

even

odd

 

 

 

 

 

 

 

Applying the idea of abstract evaluation to programs, we arrive at abstract interpretation: programs may be interpreted concretely or abstractly. Abstract interpretation of imperative programs was introduced by Sintzo [251] and studied in depth by Cousot and Cousot [65,64] and Nielson [198,200]. Here we outline the abstract interpretation of functional programs, which was pioneered by Mycroft [197].

15.1.1Variables, conditionals, and functions

An expression may contain variables: x * 3 + 7. Ordinary evaluation of this expression relies on an environment to supply a (concrete) value for x, say 8, and evaluates the expression using this value. Abstract evaluation of this expression naturally relies on an abstract environment to supply an abstract value for x, say even.

Continuing the parity example, we let EvenOdd denote the set of abstract parities. So far we have even; odd 2 EvenOdd, but we shall see that EvenOdd must have two more elements: one because of conditionals (this section), and one because of recursive de nitions (next section).

Consider a conditional expression, such as if e then 3 else 2. Clearly the abstract value of the rst branch is odd and that of the second branch is even, but what is the abstract value of the entire expression? If we could decide whether the condition e is true or false, there would be no problem, but in general we cannot.

Thus the best description we can give is `it is either even or odd': we know nothing, but so far we lack a way of saying this. We are forced to introduce a new abstract value > 2 EvenOdd (pronounced `top') to represent the absence of knowledge.

We also provide feven; odd; >g EvenOdd with an ordering v, such that even < > and odd < >. When s v t, that is, when s is less than or equal to t, then clearly s is more precise (or more informative) than t. The relation between the three abstract values can be shown as follows, with the smaller (or more informative) values below the larger (or less informative) one:

>

HHH even odd