Partial Evaluation - People.cs.uchicago.edu

advertisement

Partial Evaluation

Introduction

Partial Evaluation, also known as Program Specification , is a program optimization technique which generates specified programs by fixing one input to a particular value. In other words, if a program takes more than one input, and one of the inputs varies more slowly than the others, then specialization of the program with respect to that input gives a faster specialized program. Moreover, very many real-life programs exhibit interpretive behaviors.

A computer program can be seen as a mapping P of input data into output data:

P: {INPUT static

, INPUT dynamic

} → OUTPUT

INPUTstatic: the part of the input data known at compile time

INPUTdynamic: the part of the input data known at run time

If we write it like this:

P: INPUT static

→ {INPUT dynamic

→ OUTPUT}

The residual in the bracket can be seen as specialized program.

A partial evaluator is an algorithm which, when given a program and some of its input data, produces a residual or specialized program . Running the residual program on the remaining input data will yield the same result as running the original program on all of its input data.

This kind of computation is Staged Computation , since it is divided into several stages, including compile time, link time, run time. Details see below.

Example:

Regular expression

RE → NFA → DFA

Runtime code generation:

Packet filters

Synthesis kernel

Fast path optimization

Applications:

Visualization of Multi-dimensional data sets

Pattern recognition

Computer graphics by 'ray tracing'

Parser Generators

Two-stage computation:

Compiler : generates a target program in some target language from a source program in a source language

Parser generator : program generator to generate a parser from a context-free grammar

Compilers and parser generators first transform their input into an executable program and then run the generated program on runtime inputs for a compiler, or on a character string to be parsed. The figure compares two-step compilative program execution with one-step interpretive execution.

Give an example:

Function pow (n, x) = if (n=0) then 1 else if even (n) then ( pow (n/2, x))

2 else x * pow (n-1, x)

If we want to specialize function pow when static input x equals 3. The process is as follows: pow

3

(x) = if (3=0) then 1

else if even (3) then ( pow (3/2, x))

2

else x * pow (3-1, x) pow (2, x) = if (2=0) then 1

else if even (2) then ( pow (2/2, x))

2

else x * pow (2-1, x) pow (1, x) = if (1=0) then 1

else if even (1) then ( pow (1/2, x))

2

else x * pow (1-1, x) pow (0, x) = if (0=0) then 1

else if even (0) then ( pow (0/2, x))

2

else x * pow (0-1, x)

Thus, pow

3

(x) = x * (x * 1)

2

.

Let L be a programming language, L-program be the set of well-format program to L. If p is a program in language L, denotes its meaning, typically a function from several inputs to an output. The subscript L indicates how p is to be interpreted.

The meaning of p: input → output

Let S be a “source” language, then Interpreter:

Let T be a “target” language. Compiler S → T:

Programming Specialization:

Where r means residual program

Partial evaluation gives a remarkable approach to compilation and compiler generation.

For example, partial evaluation of an interpreter with respect to a source program yields a target program. Thus compilation can be achieved without a compiler, and a target program can be thought of as a specialized interpreter.

S-m-n theorem

Kleene presented it in 1952:

It is also called the iteration theorem, which makes use of the lambda notation introduced by Church. Let denote the recursive function of k variables with Gödel number x .

Then for every and , there exists a primitive recursive function s such that for all x , , ..., ,

A direct application of the s-m-n theorem is the fact that there exists a primitive recursive function such that

For all x and y

The s-m-n theorem is applied in the proof of the recursion theorem. The s-m-n theorem is the theoretical premise for a branch of computer science known as partial evaluation.

Mix Equation

Residual:

: A program (L-program X input) → L-program

: Executable or target 1 st

Futamura Projection

: produce compiler

: Compiler generator

2 nd

Futamura Projection

3 rd

Futamura Projection

: Self-application partial evaluation

Practice of Partial Evaluation

Definition: a computational state is a pair σ = (prog-pt, store) store: variable → value

What to classify variable as either static or dynamic?

Definition: A partial computational state is a pair (prog-pt, static-store)

Definition: A division is a classification of variables, dynamic or static classes

For example, a computation state (l, s)

Where σ s

, σ’ are static stores

Definition: A division is uniformly congruent if for any transition (l

1

, σ

1

) → (l static value of σ

2

can be computed from the static value of σ

1

, that is

2

, σ

2

); the

.

For a “flow-chart” language

Ploy: (prog-pt * static stores) → code

For example:

This online PE may cause program:

L: if y ≠ 0 then begin x := x + 1 y := y + 1 goto l target

end

Binding Time Analysis (BTA)

Simple BTA x i

are inputs, y j

are locals

L: B o

= {x i

<-> y j

| y j

belongs to {D, S}} is initial division of inputs

How to process:

1) B = B o

U {y j

-> S}

2) For a statement, y k

:= exp if exist z belongs to FV(exp) such that B(z) = D

Set B (y k

) = D

3) Repeat z until a final point

P ::= program (x

1

, x

2

… x m

, y

1

, y

2

… y m

) b

1

, b

2

… b p

B ::= l:s

S ::= x:=e; s

| goto l

| if e then goto l

1

else goto l

2

| end e

Online specialization computes program parts as early as possible and takes decisions

“on the fly” using only (and all) available information.

Offline specialization begins with BAT, whose task is to place appropriate annotations on the program before reading the static input.

2-level languages Λ

2

:

e ::= b

| x

|

λx.e

|

| e@e’ |

| if e then e’ else e’’ |

| lift e

Evaluation:

λx.e e @ e’ if e then e’ else e’’

Multi-stage languages (Meta programming)

Fun power (n,x) = if (n=0) then <1>

Else < x *

~

(power (n-1, <x>)) >

<…> means delay enclosed code by a stage

~ Means forced evaluation one stage earlier

Data specialization (1996)

Problem: after PE, some original small programs become a large number of codes, such as image processing. Data specialization aims to address the problem.

Program specification: Λ2 → static data → (dynamic data → result)

Data specialization: Λ2 → { loader: static data → cache

reader: (cache * dynamic data) → result

}

For example: dotprod (x

1

, y

1

, z

1

, x

2

, y

2

, z

2

, scale) { if scale ≠ 0 then return (x else error

1

*x

2

+ y

1

*y

2

+ z

1

*z

2

)/scale

}

After data specialization: dotprod-loader (x

1

, y

1

, x

2

, y

2

, scale) { cache → slot = x

1

*x

2

+ y

1

*y

2

} dotprod-reader (cache, z

1

, z

2

, scale) { if scale ≠ 0 then (cache → slot + z else error

1

*z

2

)/scale

}

Download