(Unreasonable Software) Reuse is Unreasonable (Software Reuse)

 

Steven Atkinson

Reusable Software Research Group

Department of Computer Science and Electrical Engineering

PO Box 6109, Morgantown, West Virginia 26506

Tel: (304)293-0405, fax: (304)293-8602

Email: atkinson@csee.wvu.edu

URL: http://www.csee.wvu.edu/~atkinson/

 

Abstract

To perform component-based software reasoning is to attempt to show that all components in a software system, when executing in concert, behave and perform as specified. In this paper it is argued that the reuse of software components which preclude such reasoning is itself an unreasonable, but unfortunately commonly accepted, practice. To change this situation, component-based software reasoning must be easily reproducible, offer the highest levels of assurance, and be both understandable and beneficial to novice software engineers. The efficacy of such a component-based software reasoning system is being investigated via a prototype reasoning tool under development at West Virginia University, called the RESOLVE Reasoning tool.

 

Keywords: component-based software reasoning, software verification, software specification

Workshop Goals:

Working Groups: testing and verification for reuse, component issues

 

1 Background

To perform component-based software reasoning is to attempt to show that all components in a software system, when executing in concert, behave and use resources as specified. There are two necessary requirements for such component-based software reasoning:

We ought to be able, as a matter of course in every day component-based software development, to reason about system correctness and performance. In a recent article in BYTE magazine, Donald Knuth[Knuth96] argues for such a reasoning system:

``They haven't yet built a reliable way to reason about these programs; that is, we still lack the mathematical proof to ensure that a program will work. With object-oriented programs, we have much less of an understanding of how we would ever prove that they don't have bugs. This is a huge gap. If people can understand OOP, they ought to be able to prove that the programs are correct.''

 

2 Position

The way we develop a software system must not of itself impinge on our ability to reason about the behavior or performance of that software system. Yet the software development paradigms in use today produce software components that are often impossible to automatically reason about, since they usually lack mechanizable specifications, upon which we crucially rely in the automated reasoning process.

This lack of ability to reason about components developed using current development paradigms should preclude the long-term reuse of these "unreasonable" components. It then becomes important to investigate whether practical techniques for component-based software specification and reasoning can be discovered, and then whether such techniques can be made cognitively and economically attractive.

 

3 Approach

In this section we first examine some reasons why the reuse of "unreasonable" components should itself be regarded as an unreasonable practice. Subsequently, we describe the design of a reasoning tool that is designed to support automated component-based software reasoning.

3.1 Unreasonable Software Reuse

Software components with well-founded abstractions and informally specified interfaces are being used and re-used with reliable and predictable results. Are such components not viable candidates for continual reuse? No. There are cultural, economic, and scientific reasons why repeated decisions to reuse these "unreasonable" components cannot be supported:

This culture is highlighted when one compares the process of software engineering with that of chemical manufacturing: manufacture of today's software components is akin to the manufacture of illicit drugs outside controlled laboratories. Trade in such goods is rampant and lucrative, but consumers are never sure of the composition and quality of the goods they are buying. The short-term fix provided by the goods creates psychological and economic dependencies with their users.

3.2 A Component-Based Reasoning Tool

The RESOLVE Reasoning Tool (RRT) is a tool for component-based software reasoning that supports reasoning about software components' functional correctness. It has been designed to support reproducible automated reasoning, understandability of such reasoning, and a "lazy" reasoning process, whereby developers can defer or delegate the discharging of proof obligations. We now give a brief outline of the assumptions and functionality of the RRT.

The RRT operates under the assumption that each and every software component implementation has an explicit mathematical model of its state and operations. Constraints on these mathematical models (which are usually as simple as sets, functions, and relations between entities) are used to form pre- and post-conditions for the component's operations. The mathematical models and the constraints on programming types and operations together form the specification for the component. Under this assumption the RRT accepts the following inputs:

 

Given those inputs, the RRT produces two outputs: a symbolic reasoning table (SRT) and a corresponding PVS theory file (see tables over-leaf).

state0

path condition0

facts0

obligations0

A SRT takes the form of a sequence of rows. Alternate rows represent reasoning states and program statements (i.e. code) from the PUV. Each reasoning state comprises:

  • a path condition (pc), i.e. assertions derived from control-flow paths followed to reach this state,
  • a set of facts (f), i.e. assertions from the post-condition of the previous statement, and
  • a set of obligations (ob) that must hold to execute the next statement, i.e. assertions derived from the pre-condition of the following statement.

PUV statement1

...

statek-1

path conditionk-1

factsk-1

obligationsk-1

PUV statementk

statek

path conditionk

factsk

obligationsk

...

PUV statementn

staten

path conditionn

factsn

obligationsn

 

PUV: THEORY
BEGIN

IMPORTING <SFW theory files>

obligation0: THEOREM
   (pc0 IMPLIES f0 AND
   pc0) IMPLIES ob0

obligationk-1: THEOREM
   (pc0 IMPLIES f0 AND
    ...
    pck-1 IMPLIES fk-1 AND
    pck-1) IMPLIES obk-1

obligationk: THEOREM
   (pc0 IMPLIES f0 AND
    ...
    pck-1 IMPLIES fk-1 AND
    pck IMPLIES fk AND
    pck) IMPLIES obk

obligationn: THEOREM
   (pc0 IMPLIES f0 AND
    ...
    pck-1 IMPLIES fk-1 AND
    pck IMPLIES fk AND
    ...
    pcn IMPLIES fn AND
    pcn) IMPLIES obn
    
END PUV

(Note that facts0 are taken from PUV's pre-condition, and obligationsn are taken from PUV's post-condition.)

The purpose of the RRT is to state whether the given PUV is correct with respect to its specification; that is, assuming the PUV's precondition is met, when its statements are executed, does its post-condition hold? This is equivalent to asking if each obligation in all reasoning states of the SRT can be discharged. An obligation in a state k can be discharged if the following formula holds:    [ [ pci implies fi (for i in 0..k) ]  and pck ] implies obk .

To determine correctness, the RRT generates PVS theory files having the general structure shown to the left. A theory named after the PUV is created, and theories derived from SFW specifications are imported. Each SRT obligation is then translated into a theorem to be discharged within the PUV theory. These theorems follow the form identified above. To discharge these theorems, the PVS theory is then loaded into a PVS session under Emacs and manually discharged. It is expected that once more experience with the theorem prover is gained, strategies directing proof step sequencing will lead to more automated reasoning.

The current version of the RRT can generate SRTs and PVS theories for the usual assortment of imperative statements, notably including loop statements and procedure calls (even for recursive calls to PUV).

 

A number of procedures have been proven correct using the RRT tool, including a procedure that appends a generic queue onto another generic queue, and a procedure that replicates instances of a generic container class. The RRT is one tool in a prototype development environment for component-based software, called the "Software Composition Workbench". The scope of the RRT in the workbench project is being extended to support generation and discharging of proof obligations for (1) module-level correctness, (2) module-level compositions (adaptation/instantiation obligations), (3) component time and space performance obligations, and (4) predicate subtype constraints[Rushby98] arising from a type-checking process.

 

4 Comparison

A number of existing component-based software engineering languages have recognized that the necessity of reasoning. Of prominence among them are Eiffel[Meyer97] which allows software engineers to "dynamically reason" about their code by running their code in a number of "assertion-checking" modes. The RRT explores the benefit of "static reasoning" using full first-order predicate logic. Meyer[Meyer97, p400] speaks to this issue:

"Eiffel's assertion mechanism...stops at the point of diminishing return -- the threshold beyond which the benefits of more formality might start being offset by the decrease of learnability, simplicity and efficiency. I have been surprised that...the threshold has not moved. Our field (software engineering) needs more formality, but the profession has not realized it yet."

A number of tools using theorem provers to support software reasoning have been developed. A tool for DisCo specifications generates proof obligations as PVS theories[Kellomäki97]. The Cogito method uses the Ergo theorem prover to discharge proof obligations generated from Sum specifications[Hamilton97]. The RRT generates a human-readable output (the SRT), and explicitly relies upon the specifications of other components in the system, rather than their (presumably more complicated) implementations.

The design of the RRT recognizes that software reasoning is mathematical reasoning: each component has a specification expressed in terms of a mathematical model. Lamport[Lamport97, p24] argues that this assumption is currently unrealistic, but desirable:

"But in 1997, the unfortunate reality is that engineers rarely specify and reason formally about the systems they build. It is naive to expect them to go to the extra effort of proving properties of open-system component specifications because they might re-use those components in other systems. It seems unlikely that reasoning about the composition of open-systems specifications will be a practical concern within the next 15 years."

The RRT is a small step towards a practical method for component-based software reasoning; the eventual availability of such reasoning systems will eliminate the need to reuse the "unreasonable" components of today. Hoare [Hoare97, p577] claims that the adoption of new ideas takes time:

"...techniques of formalization and proof have played an essential role in validating and progressing the research (of the software engineering field). However, technology transfer is extremely slow in software, as it should be in any serious branch of engineering."

In the meantime, unreasonable reuse is the order of the day.

 

References

[Knuth96] Knuth, D. Interviewed by D. Andrews, Byte (Sep. 1996); also available from "http://www.byte.com/art/9609/sec3/art19.htm" (viewed on Nov. 2, 1998)

[Meyer97] Meyer, Bertrand, "Object Oriented Software Construction" (2nd edition), Prentice Hall, 1997, ISBN 0-13-629155-4.

[Kellomäki97] Kellomäki, P. "Verification of Reactive Systems Using DisCo and PVS" In Industrial Applications and Strengthened Foundations of Formal Methods (FME'97), number 1313 in Lecture Notes in Computer Science, pp. 589-604, Springer-Verlag, 1997.

[Hamilton97] Hamilton N., Hazel D., Kearney P., Traynor O., and Wildman L. "A Complete Formal Development using Cogito", Technical report 97-46, Software Verification Research Centre, School of Information Technology, The University of Queensland, Brisbane 4072, Australia, December 1997.

[Lamport97] Lamport, L. "Composition: A Way to Make Proofs Harder" SRC Technical Note 1997-30a, Digital Systems Research Center, Palo Alto, California, December 1997.

[Rushby98] Rushby, J., Owre, S. and Shankar, N. "Subtypes for Specifications: Predicate Subtyping in PVS" IEEE Trans. Softw. Eng, Vol. 24, No. 9, September 1998, pp. 709-720.

[Hoare96] Hoare, C.A.R. "How Did Software Get So Reliable Without Proof?" In Industrial Benefit and Advances in Formal Methods (FME '96), number 1051 in Lecture Notes in Computer Science, pp. 576-594, Springer-Verlag, 1996.

 

Biography

Steven Atkinson is a post-doctoral research associate at West Virginia University. He is currently leading a team of graduate students in ongoing development of a "software composition workbench", investigating the benefits of formal component-based software engineering. He completed his doctorate on a formal approach to the design of software reuse libraries at the Software Verification Research Centre. His research interests include language semantics, and scalable techniques for the verification of software system correctness and performance.