-
Coding Guidelines and Undecidability
Authors:
Roberto Bagnara,
Abramo Bagnara,
Patricia M. Hill
Abstract:
The C and C++ programming languages are widely used for the implementation of software in critical systems. They are complex languages with subtle features and peculiarities that might baffle even the more expert programmers. Hence, the general prescription of language subsetting, which occurs in most functional safety standards and amounts to only using a "safer" subset of the language, is partic…
▽ More
The C and C++ programming languages are widely used for the implementation of software in critical systems. They are complex languages with subtle features and peculiarities that might baffle even the more expert programmers. Hence, the general prescription of language subsetting, which occurs in most functional safety standards and amounts to only using a "safer" subset of the language, is particularly applicable to them. Coding guidelines are the preferred way of expressing language subsets. Some guidelines are formulated in terms of the programming language and its implementation only: in this case they are amenable to automatic checking. However, due to fundamental limitations of computing, some guidelines are undecidable, that is, they are based on program properties that no current and future algorithm can capture in all cases. The most mature and widespread coding standards, the MISRA ones, explicitly tag guidelines with undecidable or decidable. It turns out that this information is not of secondary nature and must be taken into account for a full understanding of what the guideline is asking for. As a matter of fact, undecidability is a common source of confusion affecting many users of coding standards and of the associated checking tools. In this paper, we recall the notions of decidability and undecidability in terms that are understandable to any C/C++ programmer. The paper includes a systematic study of all the undecidable MISRA C:2012 guidelines, discussing the reasons for the undecidability and its consequences. We pay particular attention to undecidable guidelines that have decidable approximations whose enforcement would not overly constrain the source code. We also discuss some coding guidelines for which compliance is hard, if not impossible, to prove, even beyond the issue of decidability.
△ Less
Submitted 28 December, 2022;
originally announced December 2022.
-
A Rationale-Based Classification of MISRA C Guidelines
Authors:
Roberto Bagnara,
Abramo Bagnara,
Patricia M. Hill
Abstract:
MISRA C is the most authoritative language subset for the C programming language that is a de facto standard in several industry sectors where safety and security are of paramount importance. While MISRA C is currently encoded in 175 guidelines (coding rules and directives), it does not coincide with them: proper adoption of MISRA C requires embracing its preventive approach (as opposed to the "bu…
▽ More
MISRA C is the most authoritative language subset for the C programming language that is a de facto standard in several industry sectors where safety and security are of paramount importance. While MISRA C is currently encoded in 175 guidelines (coding rules and directives), it does not coincide with them: proper adoption of MISRA C requires embracing its preventive approach (as opposed to the "bug finding" approach) and a documented development process where justifiable non-compliances are authorized and recorded as deviations. MISRA C guidelines are classified along several axes in the official MISRA documents. In this paper, we add to these an orthogonal classification that associates guidelines with their main rationale. The advantages of this new classification are illustrated for different kinds of projects, including those not (yet) having MISRA compliance among their objectives.
△ Less
Submitted 23 December, 2021;
originally announced December 2021.
-
BARR-C:2018 and MISRA C:2012: Synergy Between the Two Most Widely Used C Coding Standards
Authors:
Roberto Bagnara,
Michael Barr,
Patricia M. Hill
Abstract:
The Barr Group's Embedded C Coding Standard (BARR-C:2018, which originates from the 2009 Netrino's Embedded C Coding Standard) is, for coding standards used by the embedded system industry, second only in popularity to MISRA C. However, the choice between MISRA C:2012 and BARR-C:2018 needs not be a hard decision since they are complementary in two quite different ways. On the one hand, BARR-C:2018…
▽ More
The Barr Group's Embedded C Coding Standard (BARR-C:2018, which originates from the 2009 Netrino's Embedded C Coding Standard) is, for coding standards used by the embedded system industry, second only in popularity to MISRA C. However, the choice between MISRA C:2012 and BARR-C:2018 needs not be a hard decision since they are complementary in two quite different ways. On the one hand, BARR-C:2018 has removed all the incompatibilities with respect to MISRA C:2012 that were present in the previous edition (BARR-C:2013). As a result, disregarding programming style, BARR-C:2018 defines a subset of C that, while preventing a significant number of programming errors, is larger than the one defined by MISRA C:2012. On the other hand, concerning programming style, whereas MISRA C leaves this to individual organizations, BARR-C:2018 defines a programming style aimed primarily at minimizing programming errors. As a result, BARR-C:2018 can be seen as a first, dramatically useful step to C language subsetting that is suitable for all kinds of projects; critical projects can then evolve toward MISRA C:2012 compliance smoothly while maintaining the BARR-C programming style. In this paper, we introduce BARR-C:2018, we describe its relationship with MISRA C:2012, and we discuss the parallel and serial adoption of the two coding standards.
△ Less
Submitted 15 March, 2020;
originally announced March 2020.
-
The MISRA C Coding Standard and its Role in the Development and Analysis of Safety- and Security-Critical Embedded Software
Authors:
Roberto Bagnara,
Abramo Bagnara,
Patricia M. Hill
Abstract:
The MISRA project started in 1990 with the mission of providing world-leading best practice guidelines for the safe and secure application of both embedded control systems and standalone software. MISRA C is a coding standard defining a subset of the C language, initially targeted at the automotive sector, but now adopted across all industry sectors that develop C software in safety- and/or securi…
▽ More
The MISRA project started in 1990 with the mission of providing world-leading best practice guidelines for the safe and secure application of both embedded control systems and standalone software. MISRA C is a coding standard defining a subset of the C language, initially targeted at the automotive sector, but now adopted across all industry sectors that develop C software in safety- and/or security-critical contexts. In this paper, we introduce MISRA C, its role in the development of critical software, especially in embedded systems, its relevance to industry safety standards, as well as the challenges of working with a general-purpose programming language standard that is written in natural language with a slow evolution over the last 40+ years. We also outline the role of static analysis in the automatic checking of compliance with respect to MISRA C, and the role of the MISRA C language subset in enabling a wider application of formal methods to industrial software written in C.
△ Less
Submitted 4 September, 2018;
originally announced September 2018.
-
The ACPATH Metric: Precise Estimation of the Number of Acyclic Paths in C-like Languages
Authors:
Roberto Bagnara,
Abramo Bagnara,
Alessandro Benedetti,
Patricia M. Hill
Abstract:
NPATH is a metric introduced by Brian A. Nejmeh in [13] that is aimed at overcoming some important limitations of McCabe's cyclomatic complexity. Despite the fact that the declared NPATH objective is to count the number of acyclic execution paths through a function, the definition given for the C language in [13] fails to do so even for very simple programs. We show that counting the number of acy…
▽ More
NPATH is a metric introduced by Brian A. Nejmeh in [13] that is aimed at overcoming some important limitations of McCabe's cyclomatic complexity. Despite the fact that the declared NPATH objective is to count the number of acyclic execution paths through a function, the definition given for the C language in [13] fails to do so even for very simple programs. We show that counting the number of acyclic paths in CFG is unfeasible in general. Then we define a new metric for C-like languages, called ACPATH, that allows to quickly compute a very good estimation of the number of acyclic execution paths through the given function. We show that, if the function body does not contain backward gotos and does not contain jumps into a loop from outside the loop, then such estimation is actually exact.
△ Less
Submitted 10 March, 2024; v1 submitted 25 October, 2016;
originally announced October 2016.
-
Exact Join Detection for Convex Polyhedra and Other Numerical Abstractions
Authors:
Roberto Bagnara,
Patricia M. Hill,
Enea Zaffanella
Abstract:
Deciding whether the union of two convex polyhedra is itself a convex polyhedron is a basic problem in polyhedral computations; having important applications in the field of constrained control and in the synthesis, analysis, verification and optimization of hardware and software systems. In such application fields though, general convex polyhedra are just one among many, so-called, numerical ab…
▽ More
Deciding whether the union of two convex polyhedra is itself a convex polyhedron is a basic problem in polyhedral computations; having important applications in the field of constrained control and in the synthesis, analysis, verification and optimization of hardware and software systems. In such application fields though, general convex polyhedra are just one among many, so-called, numerical abstractions, which range from restricted families of (not necessarily closed) convex polyhedra to non-convex geometrical objects. We thus tackle the problem from an abstract point of view: for a wide range of numerical abstractions that can be modeled as bounded join-semilattices --that is, partial orders where any finite set of elements has a least upper bound--, we show necessary and sufficient conditions for the equivalence between the lattice-theoretic join and the set-theoretic union. For the case of closed convex polyhedra --which, as far as we know, is the only one already studied in the literature-- we improve upon the state-of-the-art by providing a new algorithm with a better worst-case complexity. The results and algorithms presented for the other numerical abstractions are new to this paper. All the algorithms have been implemented, experimentally validated, and made available in the Parma Polyhedra Library.
△ Less
Submitted 10 August, 2009; v1 submitted 11 April, 2009;
originally announced April 2009.
-
An Improved Tight Closure Algorithm for Integer Octagonal Constraints
Authors:
Roberto Bagnara,
Patricia M. Hill,
Enea Zaffanella
Abstract:
Integer octagonal constraints (a.k.a. ``Unit Two Variables Per Inequality'' or ``UTVPI integer constraints'') constitute an interesting class of constraints for the representation and solution of integer problems in the fields of constraint programming and formal analysis and verification of software and hardware systems, since they couple algorithms having polynomial complexity with a relativel…
▽ More
Integer octagonal constraints (a.k.a. ``Unit Two Variables Per Inequality'' or ``UTVPI integer constraints'') constitute an interesting class of constraints for the representation and solution of integer problems in the fields of constraint programming and formal analysis and verification of software and hardware systems, since they couple algorithms having polynomial complexity with a relatively good expressive power. The main algorithms required for the manipulation of such constraints are the satisfiability check and the computation of the inferential closure of a set of constraints. The latter is called `tight' closure to mark the difference with the (incomplete) closure algorithm that does not exploit the integrality of the variables. In this paper we present and fully justify an O(n^3) algorithm to compute the tight closure of a set of UTVPI integer constraints.
△ Less
Submitted 1 June, 2007; v1 submitted 31 May, 2007;
originally announced May 2007.
-
On the Design of Generic Static Analyzers for Modern Imperative Languages
Authors:
Roberto Bagnara,
Patricia M. Hill,
Andrea Pescetti,
Enea Zaffanella
Abstract:
The design and implementation of precise static analyzers for significant fragments of modern imperative languages like C, C++, Java and Python is a challenging problem. In this paper, we consider a core imperative language that has several features found in mainstream languages such as those including recursive functions, run-time system and user-defined exceptions, and a realistic data and mem…
▽ More
The design and implementation of precise static analyzers for significant fragments of modern imperative languages like C, C++, Java and Python is a challenging problem. In this paper, we consider a core imperative language that has several features found in mainstream languages such as those including recursive functions, run-time system and user-defined exceptions, and a realistic data and memory model. For this language we provide a concrete semantics --characterizing both finite and infinite computations-- and a generic abstract semantics that we prove sound with respect to the concrete one. We say the abstract semantics is generic since it is designed to be completely parametric on the analysis domains: in particular, it provides support for \emph{relational} domains (i.e., abstract domains that can capture the relationships between different data objects). We also sketch how the proposed methodology can be extended to accommodate a larger language that includes pointers, compound data objects and non-structured control flow mechanisms. The approach, which is based on structured, big-step $\mathrm{G}^\infty\mathrm{SOS}$ operational semantics and on abstract interpretation, is modular in that the overall static analyzer is naturally partitioned into components with clearly identified responsibilities and interfaces, something that greatly simplifies both the proof of correctness and the implementation.
△ Less
Submitted 28 June, 2007; v1 submitted 23 March, 2007;
originally announced March 2007.
-
Applications of Polyhedral Computations to the Analysis and Verification of Hardware and Software Systems
Authors:
Roberto Bagnara,
Patricia M. Hill,
Enea Zaffanella
Abstract:
Convex polyhedra are the basis for several abstractions used in static analysis and computer-aided verification of complex and sometimes mission critical systems. For such applications, the identification of an appropriate complexity-precision trade-off is a particularly acute problem, so that the availability of a wide spectrum of alternative solutions is mandatory. We survey the range of appli…
▽ More
Convex polyhedra are the basis for several abstractions used in static analysis and computer-aided verification of complex and sometimes mission critical systems. For such applications, the identification of an appropriate complexity-precision trade-off is a particularly acute problem, so that the availability of a wide spectrum of alternative solutions is mandatory. We survey the range of applications of polyhedral computations in this area; give an overview of the different classes of polyhedra that may be adopted; outline the main polyhedral operations required by automatic analyzers and verifiers; and look at some possible combinations of polyhedra with other numerical abstractions that have the potential to improve the precision of the analysis. Areas where further theoretical investigations can result in important contributions are highlighted.
△ Less
Submitted 11 April, 2008; v1 submitted 19 January, 2007;
originally announced January 2007.
-
The Parma Polyhedra Library: Toward a Complete Set of Numerical Abstractions for the Analysis and Verification of Hardware and Software Systems
Authors:
Roberto Bagnara,
Patricia M. Hill,
Enea Zaffanella
Abstract:
Since its inception as a student project in 2001, initially just for the handling (as the name implies) of convex polyhedra, the Parma Polyhedra Library has been continuously improved and extended by joining scrupulous research on the theoretical foundations of (possibly non-convex) numerical abstractions to a total adherence to the best available practices in software development. Even though i…
▽ More
Since its inception as a student project in 2001, initially just for the handling (as the name implies) of convex polyhedra, the Parma Polyhedra Library has been continuously improved and extended by joining scrupulous research on the theoretical foundations of (possibly non-convex) numerical abstractions to a total adherence to the best available practices in software development. Even though it is still not fully mature and functionally complete, the Parma Polyhedra Library already offers a combination of functionality, reliability, usability and performance that is not matched by similar, freely available libraries. In this paper, we present the main features of the current version of the library, emphasizing those that distinguish it from other similar libraries and those that are important for applications in the field of analysis and verification of hardware and software systems.
△ Less
Submitted 18 December, 2006;
originally announced December 2006.
-
Deriving Escape Analysis by Abstract Interpretation: Proofs of results
Authors:
Patricia M. Hill,
Fausto Spoto
Abstract:
Escape analysis of object-oriented languages approximates the set of objects which do not escape from a given context. If we take a method as context, the non-escaping objects can be allocated on its activation stack; if we take a thread, Java synchronisation locks on such objects are not needed. In this paper, we formalise a basic escape domain e as an abstract interpretation of concrete states…
▽ More
Escape analysis of object-oriented languages approximates the set of objects which do not escape from a given context. If we take a method as context, the non-escaping objects can be allocated on its activation stack; if we take a thread, Java synchronisation locks on such objects are not needed. In this paper, we formalise a basic escape domain e as an abstract interpretation of concrete states, which we then refine into an abstract domain er which is more concrete than e and, hence, leads to a more precise escape analysis than e. We provide optimality results for both e and er, in the form of Galois insertions from the concrete to the abstract domains and of optimal abstract operations. The Galois insertion property is obtained by restricting the abstract domains to those elements which do not contain garbage, by using an abstract garbage collector. Our implementation of er is hence an implementation of a formally correct escape analyser, able to detect the stack allocatable creation points of Java (bytecode) applications.
This report contains the proofs of results of a paper with the same title and authors and to be published in the Journal "Higher-Order Symbolic Computation".
△ Less
Submitted 28 July, 2006; v1 submitted 24 July, 2006;
originally announced July 2006.
-
Widening Operators for Weakly-Relational Numeric Abstractions (Extended Abstract)
Authors:
Roberto Bagnara,
Patricia M. Hill,
Elena Mazzi,
Enea Zaffanella
Abstract:
We discuss the divergence problems recently identified in some extrapolation operators for weakly-relational numeric domains. We identify the cause of the divergences and point out that resorting to more concrete, syntactic domains can be avoided by researching suitable algorithms for the elimination of redundant constraints in the chosen representation.
We discuss the divergence problems recently identified in some extrapolation operators for weakly-relational numeric domains. We identify the cause of the divergences and point out that resorting to more concrete, syntactic domains can be avoided by researching suitable algorithms for the elimination of redundant constraints in the chosen representation.
△ Less
Submitted 10 December, 2004;
originally announced December 2004.
-
Finite-Tree Analysis for Constraint Logic-Based Languages: The Complete Unabridged Version
Authors:
Roberto Bagnara,
Roberta Gori,
Patricia M. Hill,
Enea Zaffanella
Abstract:
Logic languages based on the theory of rational, possibly infinite, trees have much appeal in that rational trees allow for faster unification (due to the safe omission of the occurs-check) and increased expressivity (cyclic terms can provide very efficient representations of grammars and other useful objects). Unfortunately, the use of infinite rational trees has problems. For instance, many of…
▽ More
Logic languages based on the theory of rational, possibly infinite, trees have much appeal in that rational trees allow for faster unification (due to the safe omission of the occurs-check) and increased expressivity (cyclic terms can provide very efficient representations of grammars and other useful objects). Unfortunately, the use of infinite rational trees has problems. For instance, many of the built-in and library predicates are ill-defined for such trees and need to be supplemented by run-time checks whose cost may be significant. Moreover, some widely-used program analysis and manipulation techniques are correct only for those parts of programs working over finite trees. It is thus important to obtain, automatically, a knowledge of the program variables (the finite variables) that, at the program points of interest, will always be bound to finite terms. For these reasons, we propose here a new data-flow analysis, based on abstract interpretation, that captures such information.
△ Less
Submitted 27 April, 2004; v1 submitted 26 April, 2004;
originally announced April 2004.
-
Enhanced sharing analysis techniques: a comprehensive evaluation
Authors:
Roberto Bagnara,
Enea Zaffanella,
Patricia M. Hill
Abstract:
Sharing, an abstract domain developed by D. Jacobs and A. Langen for the analysis of logic programs, derives useful aliasing information. It is well-known that a commonly used core of techniques, such as the integration of Sharing with freeness and linearity information, can significantly improve the precision of the analysis. However, a number of other proposals for refined domain combinations…
▽ More
Sharing, an abstract domain developed by D. Jacobs and A. Langen for the analysis of logic programs, derives useful aliasing information. It is well-known that a commonly used core of techniques, such as the integration of Sharing with freeness and linearity information, can significantly improve the precision of the analysis. However, a number of other proposals for refined domain combinations have been circulating for years. One feature that is common to these proposals is that they do not seem to have undergone a thorough experimental evaluation even with respect to the expected precision gains. In this paper we experimentally evaluate: helping Sharing with the definitely ground variables found using Pos, the domain of positive Boolean formulas; the incorporation of explicit structural information; a full implementation of the reduced product of Sharing and Pos; the issue of reordering the bindings in the computation of the abstract mgu; an original proposal for the addition of a new mode recording the set of variables that are deemed to be ground or free; a refined way of using linearity to improve the analysis; the recovery of hidden information in the combination of Sharing with freeness information. Finally, we discuss the issue of whether tracking compoundness allows the computation of more sharing information.
△ Less
Submitted 26 January, 2004;
originally announced January 2004.
-
A correct, precise and efficient integration of set-sharing, freeness and linearity for the analysis of finite and rational tree languages
Authors:
Patricia M. Hill,
Enea Zaffanella,
Roberto Bagnara
Abstract:
It is well-known that freeness and linearity information positively interact with aliasing information, allowing both the precision and the efficiency of the sharing analysis of logic programs to be improved. In this paper we present a novel combination of set-sharing with freeness and linearity information, which is characterized by an improved abstract unification operator. We provide a new ab…
▽ More
It is well-known that freeness and linearity information positively interact with aliasing information, allowing both the precision and the efficiency of the sharing analysis of logic programs to be improved. In this paper we present a novel combination of set-sharing with freeness and linearity information, which is characterized by an improved abstract unification operator. We provide a new abstraction function and prove the correctness of the analysis for both the finite tree and the rational tree cases. Moreover, we show that the same notion of redundant information as identified in (Bagnara et al. 2002; Zaffanella et al. 2002) also applies to this abstract domain combination: this allows for the implementation of an abstract unification operator running in polynomial time and achieving the same precision on all the considered observable properties.
△ Less
Submitted 26 January, 2004;
originally announced January 2004.
-
Branching: the Essence of Constraint Solving
Authors:
Antonio J. Fernandez,
Patricia M. Hill
Abstract:
This paper focuses on the branching process for solving any constraint satisfaction problem (CSP). A parametrised schema is proposed that (with suitable instantiations of the parameters) can solve CSP's on both finite and infinite domains. The paper presents a formal specification of the schema and a statement of a number of interesting properties that, subject to certain conditions, are satisfi…
▽ More
This paper focuses on the branching process for solving any constraint satisfaction problem (CSP). A parametrised schema is proposed that (with suitable instantiations of the parameters) can solve CSP's on both finite and infinite domains. The paper presents a formal specification of the schema and a statement of a number of interesting properties that, subject to certain conditions, are satisfied by any instances of the schema.
It is also shown that the operational procedures of many constraint systems including cooperative systems) satisfy these conditions.
Moreover, the schema is also used to solve the same CSP in different ways by means of different instantiations of its parameters.
△ Less
Submitted 24 September, 2001;
originally announced September 2001.
-
Soundness, Idempotence and Commutativity of Set-Sharing
Authors:
Patricia M. Hill,
Roberto Bagnara,
Enea Zaffanella
Abstract:
It is important that practical data-flow analyzers are backed by reliably proven theoretical results. Abstract interpretation provides a sound mathematical framework and necessary generic properties for an abstract domain to be well-defined and sound with respect to the concrete semantics. In logic programming, the abstract domain Sharing is a standard choice for sharing analysis for both practi…
▽ More
It is important that practical data-flow analyzers are backed by reliably proven theoretical results. Abstract interpretation provides a sound mathematical framework and necessary generic properties for an abstract domain to be well-defined and sound with respect to the concrete semantics. In logic programming, the abstract domain Sharing is a standard choice for sharing analysis for both practical work and further theoretical study. In spite of this, we found that there were no satisfactory proofs for the key properties of commutativity and idempotence that are essential for Sharing to be well-defined and that published statements of the soundness of Sharing assume the occurs-check. This paper provides a generalization of the abstraction function for Sharing that can be applied to any language, with or without the occurs-check. Results for soundness, idempotence and commutativity for abstract unification using this abstraction function are proven.
△ Less
Submitted 27 February, 2001;
originally announced February 2001.
-
Decomposing Non-Redundant Sharing by Complementation
Authors:
Enea Zaffanella,
Patricia M. Hill,
Roberto Bagnara
Abstract:
Complementation, the inverse of the reduced product operation, is a technique for systematically finding minimal decompositions of abstract domains. File' and Ranzato advanced the state of the art by introducing a simple method for computing a complement. As an application, they considered the extraction by complementation of the pair-sharing domain PS from the Jacobs and Langen's set-sharing do…
▽ More
Complementation, the inverse of the reduced product operation, is a technique for systematically finding minimal decompositions of abstract domains. File' and Ranzato advanced the state of the art by introducing a simple method for computing a complement. As an application, they considered the extraction by complementation of the pair-sharing domain PS from the Jacobs and Langen's set-sharing domain SH. However, since the result of this operation was still SH, they concluded that PS was too abstract for this. Here, we show that the source of this result lies not with PS but with SH and, more precisely, with the redundant information contained in SH with respect to ground-dependencies and pair-sharing. In fact, a proper decomposition is obtained if the non-redundant version of SH, PSD, is substituted for SH. To establish the results for PSD, we define a general schema for subdomains of SH that includes PSD and Def as special cases. This sheds new light on the structure of PSD and exposes a natural though unexpected connection between Def and PSD. Moreover, we substantiate the claim that complementation alone is not sufficient to obtain truly minimal decompositions of domains. The right solution to this problem is to first remove redundancies by computing the quotient of the domain with respect to the observable behavior, and only then decompose it by complementation.
△ Less
Submitted 23 January, 2001;
originally announced January 2001.
-
Verifying Termination and Error-Freedom of Logic Programs with block Declarations
Authors:
Jan-Georg Smaus,
Patricia M. Hill,
Andy King
Abstract:
We present verification methods for logic programs with delay declarations. The verified properties are termination and freedom from errors related to built-ins. Concerning termination, we present two approaches. The first approach tries to eliminate the well-known problem of speculative output bindings. The second approach is based on identifying the predicates for which the textual position of…
▽ More
We present verification methods for logic programs with delay declarations. The verified properties are termination and freedom from errors related to built-ins. Concerning termination, we present two approaches. The first approach tries to eliminate the well-known problem of speculative output bindings. The second approach is based on identifying the predicates for which the textual position of an atom using this predicate is irrelevant with respect to termination. Three features are distinctive of this work: it allows for predicates to be used in several modes; it shows that block declarations, which are a very simple delay construct, are sufficient to ensure the desired properties; it takes the selection rule into account, assuming it to be as in most Prolog implementations. The methods can be used to verify existing programs and assist in writing new programs.
△ Less
Submitted 23 June, 2000;
originally announced June 2000.