Tan article.1

7 downloads 0 Views 143KB Size Report
among I/O statements operating on R, we intro- duce three ... is defined as the R record that will be rewritten and deleted by the ..... James H. Cross, III, Ming T. Liu, Christina M. Schober ... Manager, Research & Planning: JOHN C. KEATON.
.

Researcher’s CORNER

Program slicing helps isolate program components during debugging and analysis. Of ten, however, traditional methods cannot correctly slice programs that involve database operations. The authors propose a method that can.

Correct Program Slicing of Database Operations Hee Beng Kuan Tan, Nanyang Technological University Tok Wang Ling, National University of Singapore

rogram slicing, introduced by Mark Weiser, plays a significant role in many areas.1 For example, it has been applied in program debugging and testing,2 software maintenance,3-4 integrating program versions,5 and reverse engineering.6-7 In many commercially available tools for reverse engineering (such as Viasoft), program slicing also plays an important role. During program debugging, programmers work backward from the statement and variables of a bug appearance, analyzing those statements that may affect the variables’ values just before the statement executes. Program slicing helps programmers mentally extract those statements and understand them. Database programs maintain information that supports an organization’s operation, control, and management. When these programs process a business transaction—such as a cash withdrawal in a banking system—they keep the affected database current with input/output operations: retrieval, insertion, modification, and deletion. The programs also produce reports and answer database queries. Database operations and other I/O operations constitute a program’s external interface and thus are often the program’s most important elements.

P

0740-7459/98/$10.00 © 1998 IEEE

March/ April 1998

IEEE Software

105

.

Researcher’s CORNER

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

#define YES 1 #define NO 0 main() { int c, nl, nw, nc, inword; inword = NO; nl = 0; nw = 0; nc = 0; c = getchar(); while (c ! = EOF){ nc = nc + 1; if (c == ‘\n’) nl = nl + 1; if (c == ‘’ || c == ‘\n’ || c == ‘\t’) inword = NO; else if (inword == NO) { inword = YES; nw = nw + 1; } c = getchar(); } printf(“%d \n”, nl); printf(“%d \n”, nw); printf(“%d \n”, nc); }

Figure 1. A small program to be sliced.

However, traditional program slicing may not correctly slice I/O statements that operate on a database. For example, program slicing may not be able to compute a slice that contains only those program statements suspected of affecting I/O. We propose an approach to program slicing that can be applied to both conventional files and databases and that slices I/O statements correctly.

TRADITIONAL PROGRAM SLICING Program slicing restricts program behavior to the specified subset you select. Program slices can be produced automatically by analyzing a program’s data and control flows. Starting from a statement n and a set of variables V, slicing reduces a program P to a minimal form containing only the statements that might affect, just before n executes, the values

106

IEEE Software

March/ April 1998

of variables in V. The slice is an executable program that you obtain by deleting zero or more statements from P. The statement n itself is in the slice. You can have many different slices for a given program and slicing criterion; each slicing criterion consists of a set of variables and a statement in the program. Generally, the smaller the portion of a program the slice captures, the easier it is to understand; thus, the smaller the slice, the better. Finding statement-minimal slices is generally unsolvable,1 but you can compute approximate good slices on source programs automatically by analyzing data flow and control flow.8 Traditional program slicing operates as follows. Let v and n be a program variable and statement respectively. We say v is defined at n (or n defines v) if n assigns a value to v. To avoid the details of a particular language, program slicing processes the program’s flow graph. Each node in the graph corresponds to a single program source-language statement. When computing a program slice of program P on a set of variables V at statement n, a set of variables called the active set is associated with each program statement. The active set at statement k is the subset of variables in P whose values just before execution of k might influence values of variables in V just before execution of statement n. The computation of active sets helps identify what statements to include in the slice. All statements that define variables in the active sets of their successors are included in the slice. The computation of active sets is carried out in parallel with the determination of whether to include a statement in a slice. To include the required control flow, you associate with each statement a static set of control statements to be included in any slice containing that program statement. This set of control statements is called the program statement’s control set. For a statement contained directly in a selection or iteration construct, its control set contains only the statement that defines the construct. Figure 1 shows a program to be sliced. Figure 2 shows its flow graph, and control and active sets (described later). At each node, the top set (the set with integer members) is the node’s control set. Briefly, a program slice on program P on set of variables V at statement n is computed as follows.4 You first initialize all active sets to the empty set except for the set associated with statement n, which you initialize to V. Next, include statement n is in the slice. Then, starting from the last statement in the slice (initially statement n), iterate over P to ex-

.

{} 6 7 8 9 {} {} {} {} {inword} {inword} {nw, inword}

10

11

{} {nw, inword} {}

{nw, inword, c} tract all other required statements for inclusion in the pro{11, 22} gram slice until the slice has sta{nw, inword, c} 12 bilized—that is, until you can add no further statements to the slice {11, 22} that resulted from the previous {nw, inword, c} 13 {13} iteration. Each iteration pro14 {nw, inword, c} {11, 22} cesses the statements in P, start{nw, inword, c} 15 ing from the last statement in{15} cluded in the slice to the first {nw, inword} statement in P. In each iteration, 17 {17, 20} for each statement k processed, 18 {nw} if some of the variables defined {15} at statement k are in the union of {nw} 16 {17, 20} the active sets at the successors 19 {nw, inword} of k, include k in the slice if it has not already been included. When {15} 20 {nw, inword} k is included in the slice, all the {11, 22} statements in the control set of k {nw, inword} 21 are also included. Furthermore, during the computation, for each program statement r that is not {} {} {} {} {} included in the slice, the active {nw, inword, c} {nw} {nw} {nw} {nw} set at r is set to the union of the 22 23 24 25 26 active sets at all its successors. For each program statement s included in the slice, set the active Figure 2. The flow graph, control sets, and active sets for the program shown in set at s to the union of the folFigure 1. lowing two sets: ♦ the union of the active sets at the successors of s with all the variables defined at s being removed, and enced by included statements, are also included, and ♦ the set of variables referenced at s. so on, until no further statement must be included. If a statement outputs a variable in its active set, also include that statement in the slice. DATABASE OPERATIONS For computing a slice of the program shown in IN PROGRAMS Figure 1 on nw at statement 26, Figure 2 shows the active set at each statement of the program in its flow Traditional program slicing fails to handle datagraph. For each statement (node), the bottom set (the base operations in database application programs. set with variable names as its members) is the stateOur prototype system implements an augmented ment’s active set. Figure 3 shows the resulting proslicing procedure that we believe addresses this gram slice. In the computation of the slice, statement shortcoming. We drew the examples that follow 26 is the first statement you include because you slice from our prototype file and database program slicer at this statement. Since statement 24 outputs nw, for Cobol programs. We chose to slice on Cobol prowhich is in its active set, you include that statement grams because most database applications used in the slice as well. You include statement 19 because today were developed in Cobol many years ago. it defines nw, which is in the active set of its successor. The inputs accepted and outputs delivered, and Once you include statement 19, the slice also includes the database records retrieved and updated in a all statements in the control set of statement 19: stateprogram, constitute its external interfaces. As such, ments 17 and 20. Consequently, all statements in the a program slice on a database I/O statement usucontrol sets of those statements included, and all ally creates a minimal form of the program, one that statements that may affect values of variables refer-

March/ April 1998

IEEE Software

107

.

1 2 3 4 5 6 8 10 11 15 16 17 18 19 20 21 22 24 26

#define YES 1 #define NO 0 main() { int c, nw, inword; inword = NO; nw = 0; c = getchar(); while (c ! = EOF){ if (c == ‘’ || c == ‘\n’ || c == ‘\t’) inword = NO; else if (inword == NO) { inword = YES; nw = nw + 1; } c = getchar(); } printf(“%d \n”, nw); }

Figure 3. Slice on nw at statement 26 of the program shown in Figure 1.

1 2 3 4 5

6

7 8 9

10 11 12

13 14

Open customer file for updating. Display a screen for entering a customer no. and its new address Accept the data entered Do-Until (no more data entered) Move the customer no. entered to the key of customer record area Read the customer file by direct access using the key value in its record area invalid key move “yes” to invalid-customer-no If invalid-customer-no not = “yes” Move the address entered to the address of the customer record Rewrite the customer record End-If Display a screen for entering a customer no. and its new address Accept the data entered End-Do

Figure 4. A pseudocode Cobol program with database retrieval and updating statement to be sliced.

108

IEEE Software

March/ April 1998

performs an external function provided in the program. These slices are candidates for finding reusable components. Further, I/O operations for two I/O statements not in the same slice can be performed in parallel. Therefore, slicing at I/O statements can provide a means for automatic parallelization of I/O operations. However, if there are I/O statements operating on databases in the slice, traditional program slicing may not produce a correct slice that retains the required subset of the program’s behaviors. This occurs because the traditional approach is based on the analysis of variables defined and referenced in a program. Such an analysis is unable to recognize that I/O statements operating on a database may affect each other through database record updates. For example, in traditional program slicing, slicing the program in Figure 4 on customer record at the READ statement (lines 6 and 7) does not include the statements for the updating of customer records (lines 8-11). This slice is shown in Figure 5. The latter statements are needed, however, for the slice to have the same behavior as the original program with regard to the reading of customer records. The customer record has four attributes: customer number, name, address, and balance. If the address in a customer record is changed more than once, then the sequence of customer records read in the slice differs from the sequence of customer records read in the original program. In particular, the sequence of customer records differs, due to the updating done after each reading by the original program’s REWRITE statement. We have not seen any method proposed in the literature that addresses this problem.

DEALING WITH DATABASE OPERATIONS IN PROGRAM SLICING If we let R be a database record type operated on by a program, then for analyzing the influence among I/O statements operating on R, we introduce three implicit variables: R.next-sq, R.next-md, and R.changes. These are not shown in the program. During program execution, R.next-sq is defined as the R record that will be read by the next SEQUENTIAL READ of R. The variable R.next-md is defined as the R record that will be rewritten and deleted by the next REWRITE and DELETE, re-

.

spectively, of R. We define R.changes as the sequence of R records updated so far. These implicit variables are defined and referenced by I/O statements operating on R according to Table 1. With the incorporation of implicit variables, traditional program slicing can deal with the influence that I/O statements exert when operating on a database. When such a statement is included in a slice, all the statements that influence the statement will also be included. For example, since the READ statement in the program shown in Figure 4 is a DIRECT READ, according to Table 1 it refers to customer.changes, which is defined at the REWRITE statement. The REWRITE statement is included in the slice of the program on customer record at the READ statement. Thus, all statements that define values for records rewritten by the REWRITE statement (line 9) and the statements in the control set of the REWRITE statement (lines 8 and 11) are included in the slice.

1

Open customer file for updating.

2

Display a screen for entering a customer no. and its new address

3

Accept the data entered

4 Do-Until (no more data entered) 5

Move the customer no. entered to the key of customer record area

6

Read the customer file by direct access using the key value in its record area

7

invalid key move “yes” to invalidcustomer-no

12

Display a screen for entering a customer no. and its new address

13

Accept the data entered

14 End-Do

Figure 5. Traditional slice on customer record at the read customer record statement.

TABLE 1 DEFINITION AND REFERENCE OF IMPLICIT VARIABLES BY I/O STATEMENTS Type of Statement

Refer

Define

Remarks

OPEN R

R.changes

R.next-sq

CLOSE R



R.next-sq, R.next-md

POSITION R

R.changes

R.next-sq

SEQUENTIAL READ R

R.next-sq

R.next-sq, R.next-md

DIRECT READ R

R.changes

R.next-sq, R.next-md

WRITE R



R.changes

REWRITE/ DELETE R

R.next-md

R.changes, R.next-md

An OPEN statement sets the record that will be read by the next SEQUENTIAL READ of R. R.changes may affect the result of the statement’s execution. A CLOSE statement sets both R.next-sq and R.nextmd to null. A positioning statement sets the record that will be read by the next SEQUENTIAL READ of R. R.changes may affect the result of the statement’s execution. A SEQUENTIAL READ statement reads R.next-sq. As a READ statement, it sets the record that will be rewritten and deleted by the next REWRITE and DELETE of R. It also sets the record that will be read by the next SEQUENTIAL READ of R. R.changes may affect the record read by a DIRECT READ R statement. The statement sets R.next-sq. It It defines R.next-md in the same way as the SEQUENTIAL READ R statement. A WRITE R statement writes a record in R. Therefore, it affects R.changes. A REWRITE AND DELETE statement rewrites and deletes R.next-md in R. Therefore, it affects R.changes. It also sets R.next-md to null.

March/ April 1998

IEEE Software

109

.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

16 17 18 19 20 21 22 23 24 25 26 27 28 29

Open result file for reading and student file for updating Move “no” to eof-student Read student file sequentially at end move “yes” to eof-student Do-Until eof-student = “yes” Move “no” to result-not-found Move 0 to tot-rec, tot-mark Move student-id from the student record to the result record area Position the result file such that the studentid ≥ the student-id in result record area invalid key move “yes” to result-not-found If result-not-found = “no” Read result file sequentially at end move “yes” to result-not-found End-If Do-Until (result-not-found = “yes”) or (student-id in result and student record areas differs) Add 1 to tot-rec Add mark to tot-mark Move tot-mark to tot-mark1 Read result file sequentially at end move “yes” to result-not-found End-Do If tot-rec not = 0 student-avg-mark = tot-mark / tot-rec rewrite student-rec End-If Read student file sequentially at end move “yes” to eof-student End-Do Close student and result files

Figure 6. A pseudocode Cobol program that processes student results to update student averages.

Consequently, the slice is the whole program. The behavior of the slice and the behavior of the original program are exactly the same with regard to reading customer records at the READ statement. Figure 6 shows another example, the computation of a program slice on student record at the last READ STUDENT RECORD statement (lines 26–27). Since the first READ STUDENT RECORD statement (lines 3–4) is a SEQUENTIAL READ, according to Table 1 it defines student.next-sq. As student.next-sq is referenced by the last READ STUDENT RECORD statement, the first READ STUDENT RECORD statement is included in the slice. Figure 7 shows the resulting slice. There are three fields in student record—student id, name, and average mark—and three fields in result record—student id, subject id, and mark. In computing a slice of the program on result

110

IEEE Software

March/ April 1998

1 2 3 4 5 26 27 28 29

Open result file for reading and student file for updating Move “no” to eof-student Read student file sequentially at end move “yes” to eofstudent Do-Until eof-student = “yes” Read student file sequentially at end move “yes” to eofstudent End-Do Close student and result files

Figure 7. Slice on student record at statements 26 and 27 for the program shown in Figure 6.

record at the last READ RESULT RECORD statement (lines 19–20), because the first READ RESULT RECORD statement (lines 12–13) is a SEQUENTIAL READ, according to Table 1 it defines result.next-sq. This READ RESULT RECORD statement is still a SEQUENTIAL READ, although it starts from the position set by the statement in lines 9 and 10. As the last READ RESULT RECORD statement references result.next-sq, the first READ RESULT RECORD statement is included. Furthermore, the READ STUDENT RECORD statements are also included as the READ RESULT RECORD statements refer to student id, which is defined by the READ STUDENT RECORD statements. Figure 8 shows the resulting slice. Each of the two slices computed in the previous example performs an external function provided in the program. The first slice reads all the student records sequentially. The second slice reads the result records for each student. Reducing a program to a slice that provides an external function in the program helps you comprehend the program’s functions. Such a program slice is more reusable and may be useful in reverse engineering to recover reusable program components.

A PROTOTYPE SLICER We have developed a prototype system for slicing structured Cobol programs because many legacy database applications are written in that language. We are currently exploring the use of slicing on database I/O statements when reverse-engineering such legacy code. Our system is written in g++ (GNU C++) running under Sun Unix and using a compiler generator developed from another project. The generator has two components, Lexgen, a lexical analyzer generator, and Pargen, a parser generator. You can obtain this prototype system for non-

.

Researcher’s CORNER

commercial use by contacting us directly. Our prototype contains two components: the translator and the slicer. We generate the translator from Lexgen and Pargen. It translates a structured Cobol program into a flow graph. For computing a program slice on a set of variables V at statement n, the slicer accepts V and n from the user. When implementing our proposed augmented slicing for Cobol, we incorporate into the slicer additional implementation details that handle specific Cobol features. For example, we treat the file description entry in the data division for a record type as a member of the control set of a database I/O statement that operates on the record type. We also include the statement that opens the database (or the file) for the record type in the control set of the I/O statement. The examples we gave in the previous section are pseudocode representations of Cobol programs sliced by our prototype system. The user input for the first example is “customer” and “6, 7,” which together instruct the system to slice on the customer record at the READ CUSTOMER RECORD statement at lines 6 and 7. The user inputs for computing the second example’s two slices are “student” and “26, 27,” and “result” and “19, 20,” respectively. In our system, each database I/O statement performs only a single database operation. However, the system can be extended to handle programs with SQL statements. We do this by making the translator expand each SQL statement into a procedure in which each database I/O statement performs only a single database operation. A linkage can be maintained between the SQL statement and each statement in the procedure. The slicer then processes the generated procedure instead of the SQL statements when computing a program slice. If a statement in the generated procedure must be included, the slicer includes the whole SQL statement. In our proposed approach, we adopt a conservative stance by assuming that a random UPDATE statement may affect any READ or POSITION statement that operates on the same record type, as shown in Table 1. This assumption guarantees that a computed slice will always have the same behavior as the original program with regard to an I/O statement operating on a database in the slice. From our experience, this assumption will not, in most cases, lead to the inclusion of unnecessary statements. On occasion our prototype may generate some slices that are larger than necessary. For example, a particular random UPDATE and READ pair might be mutually exclusive and thus neither element will affect

1 2 3 4 5 6 8 9

10 11 12 13 14 15

19 20 21 26 27 28 29

Open result file for reading and student file for updating Move “no” to eof-student Read student file sequentially at end move “yes” to eof-student Do-Until eof-student = “yes” Move “no” to result-not-found Move student-id from the student record to the result record area Position the result file such that the student-id ≥ the student-id in result record area invalid key move “yes” to result-not-found If result-not-found = “no” Read result file sequentially at end move “yes” to result-not-found End-If Do-Until (result-not-found = “yes”) or (student-id in result and student record areas differ) Read result file sequentially at end move “yes” to result-not-found End-Do Read student file sequentially at end move “yes” to eof-student End-Do Close student and result files

Figure 8. Slice on result record at statements 19 and 20 for the program shown in Figure 6.

the other. On balance, however, we feel satisfied that the trade-off of occasionally generating larger slices is worth avoiding the greater complexity that would result were we to make our method more precise.

T

raditional program slicing does not consider the influence among I/O statements that operate on databases. We have proposed a set of implicit variables to capture this influence. With the incorporation of these variables as defined or referenced in an I/O statement, program slicing can slice I/O statements correctly for database application programs. Slicing a program on an I/O statement produces a slice that performs an external function in the program. We are exploring the use of such slicing to recover reusable components when reverse-engineering legacy code. The approach we propose may also be useful in the automatic parallelization of ❖ database inputs and outputs.9-10

March/ April 1998

IEEE Software

111

.

R EFERENCES 1. M. Weiser, “Program Slicing,” IEEE Trans. Software Eng., Vol. 10, No. 4, July 1984, pp. 352-357. 2. B. Korel and J. Laski, “STAD—a System for Testing and Debugging: User Perspective,” Proc. 2nd Workshop Software Testing, Verification, and Analysis, July 1988, pp. 13-20. 3. K.B. Gallagher, “Using Program Slicing in Software Maintenance,” doctoral dissertation, Univ. Maryland, Dept. of Computer Science, Baltimore, 1989. 4. K.B. Gallagher and J.R. Lyle, “Using Program Slicing in Software Maintenance,” IEEE Trans. Software Eng., Vol. 17, No. 8, Aug. 1991, pp. 751-761. 5. S. Horwitz., J. Prins, and T. Reps, “Integrating Non-Interfering Versions of Programs,” ACM Trans. Programming Languages and Systems, Vol. 11, No. 3, July 1989, pp. 345-387. 6. J. Beck and D. Eichmann, “Program and Interface Slicing for Reverse Engineering,” Proc. 15th Int’l Conf. Software Eng., May 1993, pp. 509-518. 7. J.Q. Ning, A. Engberts, and W. Kozaczynski, “Recovering Reusable Components from Legacy Systems by Program Segmentation,” Proc. Working Conf. Reverse Eng., May 1993, pp. 64-72. 8. K. Kennedy, “A Survey of Data Flow Analysis Techniques,” Program Flow Analysis: Theory and Applications, S.S. Muchnick and N.D. Jones, eds., Prentice-Hall, Upper Saddle River, N.J., 1981. 9. R. Thakur et al., “Passion: Optimized I/O for Parallel Application,” Computer, June 1996, pp. 70-78. 10. I. Parsons et al., “PI/OT: Parallel I/O Templates,” Tech. Report, Univ. of Alberta, Canada Address questions about this article to Tan at School of Electrical and Electronic Engineering, Block S2, Nanyang Technological University, Nanyang Avenue, Singapore 639798; [email protected].

About the Authors Hee Beng Kuan Tan is a lecturer with the Information Communication Institute of Singapore (ICIS) in the School of Electrical and Electronics Engineering, Nanyang Technological University. He has 13 years of industry experience in software systems design, development, and project management. His research interests include software reuse, program slicing, and exception handling in software systems. Tan received a BSc in mathematics from Nanyang University, Singapore, and an MSc and a PhD, both in computer science, from the National University of Singapore.

Tok Wang Ling is an associate professor and deputy head of the Department of Information Systems and Computer Science at the National University of Singapore. He also serves on the program committee of several international database conferences. His research interests include data modeling, the entity-relationship approach, object-oriented data modeling, normalization theory, logic and databases, and integrity constraint checking. Ling received a BSc in mathematics from Nanyang University, Singapore, and an MMath and a PhD, both in computer science, from Waterloo University, Canada. He is a member of the IEEE and ACM.

COMPUTER SOCIETY INTERACTIVE

PURPOSE

The IEEE Computer Society is the world’s largest association of computing professionals, and is the leading provider of technical information in the field.

The IEEE Computer Society‘s Web site, http://computer.org, offers information and samples from the society’s publications and conferences, as well as a broad range of information about technical committees, standards, student activities, and more.

M E M B E R S HI P

Members receive the monthly magazine COMPUTER, discounts, and opportunities to serve (all activities are led by volunteer members). Membership is open to all IEEE members, affiliate society members, and others interested in the computer field.

B OARD OF GOVERNORS Term Expiring 1998: Elliot J. Chikofsky, JoAnne E. DeGroat, Ted G. Lewis, David Pessel, Benjamin W. Wah, Ronald Waxman, Thomas W. Williams Term Expiring 1999: Steve L. Diamond, Richard A. Eckhouse, Gene F. Hoffnagle, Tadao Ichikawa, James D. Isaak, Karl Reed, Deborah K. Scherrer Term Expiring 2000: Fiorenza C. Albert-Howard, Paul L. Borrill, Carl K. Chang, Deborah M. Cooper, James H. Cross, III, Ming T. Liu, Christina M. Schober Next Board Meeting: 5 June 1998, Quebec City, Quebec, Canada

EXECUTIVE COMMITTEE President: DORIS L. CARVER* Louisiana State University Dept. of Computer Science 294 Coates Hall Baton Rouge, LA 70803 O: (504) 388-3901 F: (504) 388-1495 [email protected] President-Elect: LEONARD L. TRIPP*

Past President: BARRY JOHNSON*

VP, Press Activities: I. MARK HAAS



VP, Educational Activities: WILLIS K. KING



VP, Conferences and Tutorials: GUYLAINE M. POLLOCK (1ST VP)*

VP, Membership Activities: DAVID PESSEL*

VP, Publications: BENJAMIN W. WAH* (2ND VP)

VP, Standards Activities:

I EEE OFFICERS President: JOSEPH BORDOGNA President-Elect: KENNETH R. LAKER Executive Director: DANIEL J. SENESE Secretary: ANTONIO C. BASTAS Treasurer: BRUCE A. EISENSTEIN VP, Educational Activities: ARTHUR W. WINSTON VP, Publications: FRIEDOLF M. SMITS VP, Regional Activities: DANIEL R. BENIGNI VP, Standards Activities: L. JOHN RANKINE VP, Technical Activities: LLOYD A. MORLEY President, IEEE-USA: JOHN R. REINERT

112

IEEE Software

March/ April 1998

JAMES D. ISAAK *

VP, Technical Activities: RONALD WAXMAN*

Secretary:

COMPUTER SOCIETY O F F I C E S Headquarters Office 1730 Massachusetts Ave. NW, Washington, DC 20036-1992 Phone: (202) 371-0101 • Fax: (202) 728-9614 E-mail: [email protected] Publications Office 10662 Los Vaqueros Cir., PO Box 3014 Los Alamitos, CA 90720-1314 General Information: Phone: (714) 821-8380 • [email protected] Membership and Publication Orders: (800) 272-6657 • Fax: (714) 821-4641 E-mail: [email protected] European Office 13, Ave. de L’Aquilon B-1200 Brussels, Belgium Phone: 32 (2) 770-21-98 • Fax: 32 (2) 770-85-05 E-mail: [email protected] Asia/Pacific Office Ooshima Building 2-19-1 Minami-Aoyama, Minato-ku, Tokyo 107, Japan Phone: 81 (3) 3408-3118 • Fax: 81 (3) 3408-3553 E-mail: [email protected]

CARL K. CHANG*

Treasurer:

E XECUTIVE STAFF

MICHEL ISRAEL*

IEEE Division V Director: MARIO R. BARBACCI



IEEE Division VIII Director: LAUREL V. KALEDA



Executive Director: T. MICHAEL ELLIOTT



*voting member of the Board of Governors †

nonvoting member of the Board of Governors

Executive Director: T. MICHAEL ELLIOTT Publisher: MATTHEW S. LOEB Director, Volunteer Services: ANNE MARIE KELLY Director, Finance & Administration: VIOLET S. DOAN Director, Information Technology & Services: ROBERT G. CARE Manager, Research & Planning: JOHN C. KEATON