Contracts in Practice

1 downloads 0 Views 7MB Size Report
Feb 26, 2014 - 151–160. ACM (2011). 26. http://kindsoftware.com. 27. Kiniry, J.R., Zimmerman, D.M.: Secret ninja formal methods. In: FM. LNCS, vol. 5014, pp.
Contracts in Practice? H.-Christian Estler, Carlo A. Furia, Martin Nordio, Marco Piccioni, and Bertrand Meyer Chair of Software Engineering, Department of Computer Science, ETH Zurich, Switzerland

arXiv:1211.4775v6 [cs.SE] 26 Feb 2014

[email protected]

Abstract. Contracts are a form of lightweight formal specification embedded in the program text. Being executable parts of the code, they encourage programmers to devote proper attention to specifications, and help maintain consistency between specification and implementation as the program evolves. The present study investigates how contracts are used in the practice of software development. Based on an extensive empirical analysis of 21 contract-equipped Eiffel, C#, and Java projects totaling more than 260 million lines of code over 7700 revisions, it explores, among other questions: 1) which kinds of contract elements (preconditions, postconditions, class invariants) are used more often; 2) how contracts evolve over time; 3) the relationship between implementation changes and contract changes; and 4) the role of inheritance in the process. It has found, among other results, that: the percentage of program elements that include contracts is above 33% for most projects and tends to be stable over time; there is no strong preference for a certain type of contract element; contracts are quite stable compared to implementations; and inheritance does not significantly affect qualitative trends of contract usage.

1

Introduction

Using specifications as an integral part of the software development process has long been advocated by formal methods pioneers and buffs. While today few people question the value brought by formal specifications, the software projects that systematically deploy them are still a small minority. What can we learn from these adopters about the practical usage of specifications to support software development? In this paper, we answer this question by looking into contracts, a kind of lightweight formal specification in the form of executable assertions (preconditions, postconditions, and class invariants). In the practice of software development, contracts support a range of activities such as runtime checking, automated testing, and static verification, and provide rigorous and unambiguous API documentation. They bring some of the advantages of “heavyweight” formal methods while remaining amenable to programmers without strong mathematical skills: whoever can write Boolean expressions can also write contracts. Therefore, learning how contracts are used in the projects that use them can shed light on how formal methods can make their way into the practice of software development. ?

Work supported by Gebert-Ruf Stiftung, by ERC grant CME # 291389, and by SNF grant ASII # 200021-134976.

The empirical study of this paper analyzes 21 projects written in Eiffel, C#, and Java, three major object-oriented languages supporting contracts, with the goal of studying how formal specifications are written, changed, and maintained as part of general software development. Eiffel has always supported contracts natively; the Java Modeling Language (JML [29]) extends Java with contracts written as comments; and C# has recently added support with the Code Contracts framework [14]. Overall, our study analyzed more than 260 million lines of code and specification distributed over 7700 revisions. To our knowledge, this is the first extensive study of the practical evolving usage of simple specifications such as contracts over project lifetimes. The study’s specific questions target various aspects of how contracts are used in practice: Is the usage of contracts quantitatively significant and uniform across the various selected projects? How does it evolve over time? How does it change with the overall project? What kinds of contracts are used more often? What happens to contracts when implementations change? What is the role of inheritance? The main findings of the study, described in Section 5, include: – The projects in our study make a significant usage of contracts: the percentages of routines and classes with specification is above 33% in the majority of projects. – The usage of specifications tends to be stable over time, except for the occasional turbulent phases where major refactorings are performed. This suggests that contracts evolve following design changes. – There is no strong preference for certain kinds of specification elements (preconditions, postconditions, class invariants); but preconditions, when they are used, tend to be larger (have more clauses) than postconditions. This indicates that different specification elements are used for different purposes. – Specifications are quite stable compared to implementations: a routine’s body may change often, but its contracts will change infrequently. This makes a good case for a fundamental software engineering principle: stable interfaces over changing implementations [41]. – Inheritance does not significantly affect the qualitative findings about specification usage: measures including and excluding inherited contracts tend to correlate. This suggests that the abstraction levels provided by inheritance and by contracts are largely complementary. As a supplemental contribution, we make all data collected for the study available online as an SQL database image [7]. This provides a treasure trove of data about practically all software projects of significant size publicly available that use contracts. Positioning: what this study is not. The term “specification” has a broad meaning. To avoid misunderstandings, let us mention other practices that might be interesting to investigate, but which are not our target in this paper. – We do not consider formal specifications in forms other than executable contracts (Section 2). – We do not look for formal specifications in generic software projects: it is wellknown [42] that the overwhelming majority of software does not come with formal specifications (or any specifications). Instead, we pick our projects among the minority of those actually using contracts, to study how the few adopters use formal specifications in practice. 2

– We do not study applications of contracts; but our analysis may serve as a basis to follow-up studies targeting applications. – We do not compare different methodologies to design and write contracts; we just observe the results of programming practices.

2

Contracts as Specification

1 class MEASURE −− Revision 1 2 3 make do create data end 4 5 data: LIST [INTEGER] −− List of data 6 7 add_datum (d: INTEGER) 8 require not data . has (d) 9 do 10 data . append (d) 11 ensure not data . is_empty 12 13 copy_data ( new_list : LIST [INTEGER]) 14 require new_list 6= Void 15 do 16 across new_list as x: add_datum (x) 17 18 invariant 19 data 6= Void

1 2 3 4 5 6 7 8

class MEASURE −− Revision 2 make do create data end data: LIST [INTEGER] −− List of data add_datum (d: INTEGER) require not data . has (d) d ≥0

9 10 11 12 13 14 15 16 17 18

do data . append (d) ensure not data . is_empty copy_data ( new_list : LIST [INTEGER]) require new_list 6= Void do if not new_list . is_empty then across new_list as x: add_datum (x)

19 20 invariant 21 data 6= Void 22

not data . is_empty

Fig. 1. Class MEASURE in revision 1 (left) and 2 (right). Lines added in revision 2 are shadowed.

Contracts [32] are the form of lightweight specification that we consider in this paper; therefore, we will use the terms “contract” and “specification” as synonyms. This section gives a concise overview of the semantics of contracts and of how they can change with the implementation. The presentation uses a simplified example written in pseudo-Eiffel code (see Figure 1) which is, however, representative of features found in real code (see Section 5). Consider a class MEASURE used to store a sequence of measures, each represented by an integer number; the sequence is stored in a list as attribute data. Figure 1 shows two revisions of class MEASURE, formatted so as to highlight the lines of code or specification added in revision 2. MEASURE includes specification elements in the form of preconditions (require), postconditions (ensure), and class invariants ( invariant ). Each element includes one or more clauses, one per line; the clauses are logically anded. For example, routine (method) add_datum has one precondition clause on line 8 and, in revision 2, another clause on line 9. Contract clauses use the same syntax as Boolean expressions of the programming language; therefore, they are executable and can be checked at runtime. A routine’s 3

precondition must hold whenever the routine is called; the caller is responsible for satisfying the precondition of its callee. A routine’s postcondition must hold whenever the routine terminates execution; the routine body is responsible for satisfying the postcondition upon termination. A class invariant specifies the “stable” object states between consecutive routine calls: it must hold whenever a new object of the class is created and before and after every (public) routine call terminates.1 In Figure 1 (left), routine add_datum must be called with an actual argument d that represents a measure not already stored in the list data (precondition on line 8); when the routine terminates, the list data must not be Void (class invariant on line 19) and not empty (postcondition on line 11). Revision 2 of class MEASURE, in Figure 1 (right), introduces changes in the code and in the specification. Some contracts become stronger: a precondition clause and a class invariant clause are added on lines 9 and 22. Routine copy_data changes its implementation: revision 2 checks whether new_list is empty (line 17) before copying its elements, so as to satisfy the new invariant clause on line 22.

3

Why We Should Care About Changing Specifications

Since specifications in the form of contracts are executable, their changes over the development of a software project may directly affect the ways in which the software is developed, and automatically tested and analyzed. We now sketch a few practical examples that motivate the empirical analysis. Testing is a widely used verification technique based on executing a system to find failures that reveal errors. Testing requires oracles [50,21,19] to determine if the call to a certain routine is valid and produces the expected result. Since contracts can be evaluated at runtime like any other program expression, they can serve as completely automatic testing oracles. Previous work (to mention just a few: [30,6,3,57,52,59,33,55,45]) has built “push button” testing frameworks that use contracts. The effective usage of contracts as oracles in software testing [17,23,1] rests on some assumptions. Besides the obvious requirements that contracts be available and maintained, how pre- and postconditions change affects the testability of routines. The stronger the precondition of a routine r is, the harder is testing the routine, because more calls to r become invalid. In Figure 1, add_datum is harder to test in revision 2 because it has a stronger precondition. On the other hand, a stronger precondition makes r’s clients more easily testable for errors, in that there is a higher chance that a test suite will trigger a precondition violation that does not comply with r’s stricter specification. This is the case of copy_data in the example of Section 2, which calls add_datum and hence may fail to satisfy the latter’s stronger precondition in revision 2. Conversely, a stronger postcondition makes a routine itself easier to test for errors. Conflict analysis. Indirect conflicts [4,38] between code maintained by different developers complicate collaborative development practices. Specifications in the form of contracts can help detect such conflicts: syntactic changes to the contract of a public routine may indicate conflicts in its clients, if the syntactic changes reflect a changed 1

The semantics of class invariants is more subtle in the general case [32] but the details are unimportant here.

4

routine semantics. Thus, using syntactic changes as indicators of possible indirect conflicts is workable only if contracts change much less frequently than implementations, so that following changes in the former generates only a limited number of warnings; and, conversely, only if specifications are consistently changed when the semantics of the implementation changes, so as to produce few false negatives. Object retrieval error detection. Changes in the attributes of a class may affect the capability to retrieve previously stored objects [35,9,43]. Class invariants help detect when inconsistent objects stored in a previous revision are introduced in the system: they express properties of the object state, and hence of attributes, that every valid object must satisfy. In Figure 1, objects stored in revision 1 with an empty data list cannot be retrieved after the code has evolved into revision 2 because they break the new class invariant. Knowing whether developers consistently add invariant clauses for describing constraints on newly introduced attributes tells us whether class invariants are reliable to detect inconsistent objects as they are retrieved.

4

Study Setup

Our study analyzes contract specifications in Eiffel, C#, and Java, covering a wide range of projects of different sizes and life spans developed by professional programmers and researchers. The following subsections present how we selected the projects; the tools we developed to perform the analysis; and the raw measures collected. 4.1

Data Selection

We selected 21 open-source projects that use contracts and are available in public repositories. Save for requiring a minimal amount of revisions (at least 30) and contracts (at least 5% of elements in the latest revisions), we included all open-source projects written in Eiffel, C# with CodeContracts, or Java with JML we could find when we performed this research. Table 2 lists the projects and, for each of them, the total number of REVisions, the life span (AGE, in weeks), the size in lines of code (LOC) at the latest revision, the number of DEVelopers involved (i.e., the number of committers to the repository), and a short description. The 8 Eiffel projects comprise some of the largest publicly available Eiffel applications and libraries, such as the EiffelBase and Gobo libraries (maintained by Eiffel Software and GoboSoft), as well as EiffelProgramAnalysis (developed by PhD students) and AutoTest (developed by our research group). We picked the C# projects available on the Code Contracts webpage [8], which lists all major C# open projects using contracts; 4 of the C# projects (Boogie, CCI, Dafny, and Quickgraph) were mainly developed by Microsoft Research. The main sources of Java projects using JML were the official JML webpage [24], and the OpenJML [39] and KindSoftware [26] projects. We screened 44 projects officially using JML, but only 6 satisfied our requirements about minimal amount of contracts and revisions. With the help of the project configuration files, we manually went through all project repositories to weed out the artifacts not part of the main application (e.g., test suites, accessory library code, or informal documentation). When a repository contained multiple 5

branches, we selected the main branch (trunk in Subversion and default in Mercurial) and excluded the others. # 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

PROJECT

LANG .

AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny LabsFramework Quickgraph Rxx Shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra Total

Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel C# C# C# C# C# C# C# Java Java Java Java Java Java

# REV. AGE # LOC # DEV. 306 195 65’625 13 1342 1006 61’922 45 208 114 40’750 8 671 747 53’316 8 282 716 21’941 6 120 524 10’840 6 215 716 6’131 7 922 285 163’552 6 766 108 88’284 29 100 171 20’602 3 326 106 29’700 19 49 30 14’540 1 380 100 40’820 4 148 68 55’932 2 59 7 2352 2 376 119 13’294 6 879 366 73’760 27 395 389 35’013 18 29 106 5’963 3 30 350 10’872 7 153 169 15’538 8 7’756 6’392 830’747 228

DESCRIPTION

Contract-based random testing tool General-purpose data structures library Utility library for analyzing Eiffel programs Library for compiler interoperability Portable data structure library Date and time library Library to support design patterns XML Library supporting XSL and XPath Program verification system Library to support compilers construction Program verifier Library to manage experiments in .NET Generic graph data structure library Library of unofficial reactive LINQ extensions Application for messaging in Twitter style Direct Verification Condition Generator An Extended Static Checker for Java (version 2) Front-end parser for Java byte and source code A logging framework Race Condition Checker for Java Editor for Java bytecode and BML specifications

Table 2. List of projects used in the study. “AGE” is in weeks, “# LOC” is lines of code, and “#D EVELOPERS” equals the number of committers to the repository.

4.2

Analysis Tools

To support analysis of large amounts of program code in multiple languages, we developed C OAT—a “COntract Analysis Tool”. The current implementation of C OAT has five main components: C OAT R EPO retrieves the complete revision history of projects; C OAT E IFFEL, C OAT C#, and C OAT JAVA are language-specific back-ends that process Eiffel and C# classes and extract contracts and code into a database; C OATA NALYZE queries the database data supplied by the back-ends and produces the raw measures discussed in Section 4.3. Finally, a set of R scripts read the raw data produced by C OATA NALYZE and perform statistical data analysis. C OAT R EPO accesses Subversion and Mercurial repositories, checks out all revisions of a project, and stores them locally together with other relevant data such as commit dates, messages, and authors. We used this additional data to investigate unexpected behavior, such as sudden extreme changes in project sizes, as we mention in Section 5. C OAT E IFFEL parses Eiffel classes, extracts body and specification elements, and stores them in a relational database, in a form suitable for the subsequent processing. While parsing technology is commonplace, parsing projects over a life span of nearly 20 years (such as EiffelBase) is challenging because of changes in the language syntax and semantics. A major question for our analysis was how to deal with inheritance. Routines and classes inherit contracts as well as implementations; when analyzing the specification of a routine or a class, should our measures include the inherited specification? Since we 6

had no preliminary evidence to prefer one approach or the other, our tools analyze each class twice: once in its flat version and once in its non-flat version. The non-flat version of a class is limited to what appears in the class text. A flat class, in contrast, explicitly includes all the routines (with their specification) and invariants of the ancestor classes. Flattening ignores, however, library classes or framework classes that are not part of the repository. Reconstructing flat classes in the presence of multiple inheritance (supported and frequently used in Eiffel) has to deal with features such as member renaming and redefinitions which introduce further complexity, and hence requires static analysis of the dependencies among the abstract syntax trees of different classes. Parsing C# is simpler because it only deals with the latest version of the language and single inheritance. The Code Contracts library has, however, its peculiarities that require some special processing to make the results comparable with Eiffel’s. For example, specifications of an interface or abstract class must appear in a separate child class containing only the contracts; our tool merges these “specification classes” with their parent. Section 5.6 compares our measures for the flat and non-flat versions of our projects; the overall conclusion is that the measures tend to be correlated. This is a useful piece of information for the continuation of our study: for the measures we took, both considering in detail and overlooking inheritance seem to lead to consistent results. C OATA NALYZE reads the data stored in the database by C OAT E IFFEL, C OAT C#, and C OAT JAVA and computes the raw measures described in Section 4.3. It outputs them to CSV files, which are finally processed by a set of R scripts that produce tables with statistics (such as Table 3) and plots (such as those next to Table 3). The complete set of statistics is available [7,13] (see the appendix). 4.3

Measures

The raw measures produced by C OATA NALYZE include: – the number of classes, the number of classes with invariants, the average number of invariant clauses per class, and the number of classes modified compared to the previous revision; – the number of routines (public and private), the number of routines with nonempty precondition, with non-empty postcondition, and with non-empty specification (that is, precondition, postcondition, or both), the average number of preand postcondition clauses per routine, and the number of routines with modified body compared to the previous revision. Measuring precisely the strength of a specification (which refers to how constraining it is) is hardly possible as it requires detailed knowledge of the semantics of classes and establishing undecidable properties in general (it is tantamount to deciding entailment for a first-order logic theory). In our study, we count the number of specification clauses (elements anded, normally on different lines) as a proxy for specification strength. The number of clauses is a measure of size that is interesting in its own right. Then, if a (non-trivial, i.e., not identically true) clause is added to a specification element without changing its other clauses, we certainly have a strengthening; and, con7

versely, a weakening when we remove a clause. If some clauses are changed,2 just counting the clauses may measure strength incorrectly. We have evidence, however, that the error introduced by measuring strengthening in this way is small. We manually inspected 277 changes randomly chosen, and found 11 misclassifications (e.g., strengthening reported as weakening). Following [31, Eq. 5], this gives a 95% confidence interval of [2%, 7%]: with 95% probability, the errors introduced by our estimate (measuring clauses for strength) involve no more than 7% of the changes.

5

How Contracts Are Used

This section presents the main findings of our study regarding what kinds of specifications programmers write and how they change the specifications as they change the system. Our study targets the following main questions, addressed in each ofthe following subsections. Q1. Do projects make a significant usage of contracts, and how does usage evolve over time? Q2. How does the usage of contracts change with projects growing or shrinking in size? Q3. What kinds of contract elements are used more often? Q4. What is the typical size and strength of contracts, and how does it change over time? Q5. Do implementations change more often than their contracts? Q6. What is the role of inheritance in the way contracts change over time? Table 3 shows the essential quantitative data we discuss for each project; Table 4 shows sample plots of the data for four projects. In the rest of the section, we illustrate and summarize the data in Table 3 and the plots in Table 4 as well as much more data and plots that, for lack of space, are available elsewhere [7,13]. 5.1

Writing Contracts

In the majority of projects in our study, developers devoted a considerable part of their programming effort to writing specifications for their code. While we specifically target projects with some specification (and ignore the majority of software that doesn’t use contracts), we observe that most of the projects achieve significant percentages of routines or classes with specification. As shown in column % ROUTINES SPEC of Table 3, in 7 of the 21 analyzed projects, on average 50% or more of the public routines have some specification (pre- or postcondition); in 14 projects, 35% or more of the routines have specification; and only 3 projects have small percentages of specified routines (15% or less). Usage of class invariants (column % CLASSES INV in Table 3) is more varied but still consistent: in 9 projects, 33% or more of the classes have an invariant; in 10 projects, 12% or less of the classes have an invariant. The standard deviation of these percentages is small for 11 of the 21 projects, compared to the average value over all revisions: the latter is at least five times larger. suggesting that deviations from the 2

We consider all concrete syntactic changes, that is all textual changes.

8

average are normally small. Section 5.2 gives a quantitative confirmation of this hint about the stability of specification amount over time. The EiffelBase project—a large standard library used in most Eiffel projects—is a good “average” example of how contracts may materialize over a project’s lifetime. After an initial fast growing phase (see the first plot in Table 4), corresponding to a still incipient design that is taking shape, the percentages of routines and classes with specification stabilize around the median values with some fluctuations that—while still significant, as we comment on later—do not affect the overall trend or the average percentage of specified elements. This two-phase development (initial mutability followed by stability) is present in several other projects of comparable size, and is sometimes extreme, such as for Boogie, where there is a widely varying initial phase, followed by a very stable one where the percentages of elements with specification is practically constant around 30%. Analyzing the commit logs around the revisions of greater instability showed that wild variations in the specified elements coincide with major reengineering efforts. For Boogie, the initial project phase coincides with the porting of a parent project written in Spec# (a dialect of C#), and includes frequent alternations of adding and removing code from the repository; after this phase, the percentage of routines and classes with specification stabilizes to a value close to the median. There are few outlier projects where the percentage of elements with specification is small, not kept consistent throughout the project’s life, or both. Quickgraph, for example, never has more than 4% of classes with an invariant or routines with a postcondition, and its percentage of routines with precondition varies twice between 12% and 21% in about 100 revisions (see complete data in [13]). In two thirds of the projects, on average 1/3 or more of the routines have some specification (pre- or postconditions). Public vs. private routines. The data analysis focuses on contracts of public routines. To determine whether trends are different for private routines, we visually inspected the plots [7] and computed the correlation coefficient3 τ for the evolution of the percentages of specified public routines against those of private routines. The results suggest to partition the projects into three categories. For the 9 projects in the first category—AutoTest, EiffelBase, Boogie, CCI, Dafny, JavaFE, Logging, RCC and Umbra—the correlation is positive (0.51 ≤ τ ≤ 0.94) and highly significant. The 2 projects in the second category—GoboStructure and Labs—have negative (τ ≤ −0.47) and also significant correlation. The remaining 10 projects belong to the third category, characterized by correlations small in absolute value, positive or negative, or statistically insignificant. This partitioning seems to correspond to different approaches to interface design and encapsulation: for projects in the first category, public and private routines always receive the same amount of specification throughout the project’s life; projects in the second category show negative correlations that may correspond to changes to the visibility status of a significant fraction of the routines; visual inspection of projects in the third category still suggests positive correlations between public and private routines with specification, but the occasional redesign upheaval reduces the overall value of τ or the confidence level. In fact, the confidence level is typically small for projects in the third category; and it is not significant (p = 0.418) only for 3

All correlation measures in the paper employ Kendall’s rank correlation coefficient τ .

9

EiffelProgramAnalysis which also belongs to the third category. Projects with small correlations tend to be smaller in size with fewer routines and classes; conversely, large projects may require a stricter discipline in defining and specifying the interface and its relations with the private parts, and have to adopt consistent approaches throughout their lives. In roughly half of the projects, the amounts of contracts in public and in private routine correlate; in the other half, correlation vanishes due to redesign changes. 5.2

Contracts and Project Size

In Section 5.1, we observed that the percentage of specified routines and classes is fairly stable over time, especially for large projects in their maturity. We analyzed the correlation between measures of elements with specification and project size, and corroborated the found correlations with visual inspection of the graphs. The correlation between the number of routines or classes with some specification and the total number of routines or classes (with or without specification) is consistently strong and highly significant. Looking at routines, 10 projects exhibit an almost perfect correlation with τ > 0.9 and p ∼ 0; only 3 projects show medium/low correlations (Labs and Quickgraph with τ = 0.48, and Logging with τ = 0.32) which are however still significant. The outlook for classes is quite similar: the correlation between number of classes with invariants and number of all classes tends to be high. Outliers are the projects Boogie and JavaFE with the smaller correlations τ = 0.28 and τ = 0.2, but visual inspection still suggests that a sizable correlation exists for Boogie (the results for JavaFE are immaterial since it has only few invariants overall). In all, the absolute number of elements with specification is normally synchronized to the overall size of a project, confirming the suggestion of Section 5.1 that the percentage of routines and classes with specification is stable over time. Having established that, in general, specification and project size have similar trends, we can look into finer-grained variations of specifications over time. To estimate the relative effort of writing specifications, we measured the correlation between percentage of specified routines or classes and number of all routines or all classes. A first large group of projects, almost half of the total whether we look at routines or classes, show weak or negligible correlations (−0.35 < τ < 0.35). In this majority of projects, the relative effort of writing and maintaining specifications evolves largely independently of the project size. Given that the overall trend is towards stable percentages, the high variance often originates from initial stages of the projects when there were few routines or classes in the system and changes can be momentous. GoboKernel and DirectVCGen are specimens of these cases: the percentage of routines with contracts varies wildly in the first 100 revisions when the system is still small and the developers are exploring different design choices and styles. Another group of 3 projects (AutoTest, Boogie, and Dafny) show strong negative correlations (τ < −0.75) both between percentage of specified routines and number of routines and between percentage of specified classes and number of classes. The usual cross-inspection of plots and commit logs points to two independent phenomena that account for the negative correlations. The first is the presence of large merges of project branches into the main branch; these give rise to strong irregularities in the absolute 10

and relative amount of specification used, and may reverse or introduce new specification styles and policies that affect the overall trends. As evident in the second plot of Table 4, AutoTest epitomizes this phenomenon, with its history clearly partitioned into two parts separated by a large merge at revision 150. Before the merge, the system is smaller with high percentages of routines and classes with specification; with the merge, the system grows manifold and continues growing afterward, while the percentage of elements with specification decreases abruptly and then (mostly for class invariants) continues decreasing. The second phenomenon that may account for negative correlations between percentage of specified elements and measures of project size is a sort of “specification fatigue” that kicks in as a project becomes mature and quite large. At that point, there might be diminishing returns for supplying more specification, and so the percentage of elements with specification gracefully decreases while the project grows in size. (This is consistent with Schiller et al.’s suggestion [49] that annotation burden limits the extent to which contracts are used.) The fatigue is, however, of small magnitude if present at all, and may be just be a sign of reached maturity where a solid initial design with plenty of specification elements pays off in the long run to the point that less relative investment is sufficient to maintain a stable level of maintainability and quality. The remaining projects have significant positive correlations (τ > 0.5) between either percentage of specified routines and number of routines or between percentage of specified classes and number of classes, but not both. In these special cases, it looks as if the fraction of programming effort devoted to writing specification tends to increase with the absolute size of the system: when the system grows, proportionally more routines or classes get a specification. However, visual inspection suggests that, in all cases, the trend is ephemeral or contingent on transient phases where the project size changes significantly in little time. As the projects mature and their sizes stabilize, the other two trends (no correlation or negative correlation) emerge in all cases. The fraction of routines and classes with some specification is quite stable over time. Local exceptions are possible when major redesign changes take place. 5.3

Kinds of Contract Elements

Do programmers prefer preconditions? Typically, one would expect that preconditions are simpler to write than postconditions (and, for that matter, class invariants): postconditions are predicates that may involve two states (before and after routine execution). Furthermore, programmers have immediate benefits in writing preconditions as opposed to postconditions: a routine’s precondition defines the valid input; hence, the stronger it is, the fewer cases the routine’s body has to deal with. Contrary to this common assumption, the data in our study (columns % ROUTINES PRE and POST in Table 3) is not consistently lopsided towards preconditions. 2 projects show no difference in the median percentages of routines with precondition and with postcondition. 10 projects do have, on average, more routines with precondition than routines with postcondition, but the difference in percentage is less than 10% in 5 of those projects, and as high as 39% only in one project (Dafny). The remaining 9 projects even have more routines with postcondition than routines with precondition, although the difference is small (less than 5%) in 5 projects, and as high as 45% only in RCC. 11

On the other hand, in 17 projects the percentage of routines with some specification (precondition, postcondition, or both) is higher than both percentages of routines with precondition and of routines with postcondition. Thus, we can partition the routines of most projects in three groups of comparable size: routines with only precondition, routines with only postcondition, and routines with both. The 4 exceptions are CCI, Shweet, DirectVCGen, and Umbra where, however, most elements have little specification. In summary, many exogenous causes may concur to determine the ultimate reasons behind picking one kind of contract element over another, such as the project domain and the different usage of different specification elements. Our data is, however, consistent with the notion that programmers choose which specification to write according to context and requirements, not based on a priori preferences. It is also consistent with Schiller et al.’s observations [49] that contract usage follows different patterns in different projects, and that programmers are reluctant to change their preferred usage patterns—and hence patterns tend to remain consistent within the same project. A closer look at the projects where the difference between percentages of routines with precondition and with postcondition is significant (9% or higher) reveals another interesting pattern. All 6 projects that favor preconditions are written in C# or Java: Dafny, Labs, Quickgraph, Shweet, ESCJava (third plot in Table 4, after rev. 400), and JavaFE; conversely, the 3 of 4 projects that favor postconditions are in Eiffel (AutoTest, GoboKernel, and GoboTime), whereas the fourth is RCC written in Java. A possible explanation for this division involves the longer time that Eiffel has supported contracts and the principal role attributed to Design by Contract within the Eiffel community. C# and Java programmers, then, are more likely to pragmatically go for the immediate tangible benefits brought by preconditions as opposed to postconditions; Eiffel programmers might be more zealous and use contracts thoroughly also for design before implementation. Preconditions and postconditions are used equally frequently across most projects. Class invariants. Class invariants have a somewhat different status than pre- or postconditions. Since class invariants must hold between consecutive routine calls, they define object consistence, and hence they belong to a different category than pre- and postconditions. The percentages of classes with invariant (% CLASSES INV in Table 3) follow similar trends as pre- and postconditions in most projects in our study. Only 4 projects stick out because they have 4% or less of classes with invariant, but otherwise make a significant usage of other specification elements: Quickgraph, EiffelProgramAnalysis, Shweet, and DirectVCGen.4 Compared to the others, Shweet has a short history and EiffelProgramAnalysis involves students as main developers rather than professionals. Given that the semantics of class invariants is less straightforward than that of pre- and postconditions—and can become quite intricate for complex programs [2]— this might be a factor explaining the different status of class invariants in these projects. A specific design style is also likely to influence the usage of class invariants, as we further comment on in Section 5.4. Kinds of constructs. An additional classification of contracts is according to the constructs they use. We gathered data about constructs of three types: expressions in4

While the projects CCI and Umbra have few classes with invariants (4%–6%), we don’t discuss them here because they also only have few routines with preconditions or postconditions.

12

volving checks that a reference is Void (Eiffel) or null (C# and Java); some form of finite quantification (constructs for ∀/∃ over containers exist for all three languages); and old expressions (used in postconditions to refer to values in the pre-state). Void/null checks are by far the most used: in Eiffel, 36%–93% of preconditions, 7%–62% of postconditions, and 14%–86% of class invariants include a Void check; in C#, 80%–96% of preconditions contain null checks, as do 34%–92% of postconditions (the only exception is CCI which does not use postconditions) and 97%–100% of invariants (exceptions are Quickgraph at 20% and Shweet which does not use invariants); in Java, 88%–100% of preconditions, 28%–100% of postconditions, and 50%–77% of class invariants contain null (with the exception of Umbra which has few contracts in general). Void/null checks are simple to write, and hence cost-effective, which explains their wide usage; this may change in the future, with the increasing adoption of static analyses which supersede such checks [34,10]. The predominance of simple contracts and its justification have been confirmed by others [49]. At the other extreme, quantifications are very rarely used: practically never in preor postconditions; and very sparsely (1%–10% of invariants) only in AutoTest, Boogie, Quickgraph, ESCJava, and JavaFE’s class invariants. This may also change in the future, thanks to the progresses in inferring complex contracts [20,54,53], and in methodological support [45]. The usage of old is more varied: C# postconditions practically don’t use it, Java projects rarely use it (2%–3% of postconditions at most), whereas it features in as many as 39% of postconditions for some Eiffel projects. Using old may depend on the design style; for example, if most routines are side-effect free and return a value function solely of the input arguments there is no need to use old. The overwhelming majority of contracts involves Void/null checks. In contrast, quantifiers appear very rarely in contracts. 5.4

Contract Size and Strength

The data about specification size (and strength) partly vindicates the intuition that preconditions are more used. While Section 5.3 showed that routines are not more likely to have preconditions than postconditions, preconditions have more clauses on average than postconditions in all but the 3 projects GoboTime, ESCJava, and Logging. As shown in columns AVG ROUTINES PRE and POST of Table 3, the difference in favor of preconditions is larger than 0.5 clauses in 9 projects, and larger than 1 clause in 3 projects. CCI never deploys postconditions, and hence its difference between preand postcondition clauses is immaterial. GoboTime is a remarkable outlier: not only do twice as many of its routines have a postcondition than have precondition, but its average postcondition has 0.66 more clauses than its average precondition. ESCJava and Logging also have larger postconditions on average but the size difference is less conspicuous (0.25 and 0.32 clauses). We found no simple explanation for these exceptions, but they certainly are the result of deliberate design choices. The following two facts corroborate the idea that programmers tend to do a better job with preconditions than with postconditions—even if they have no general preference for one or another. First, the default “trivial” precondition true is a perfectly 13

reasonable precondition for routines that compute total functions—defined for every value of the input; a trivial postcondition is, in contrast, never satisfactory. Second, in general, “strong” postconditions are more complex than “strong” preconditions [45] since they have to describe more complex relations. Class invariants are not directly comparable to pre- and postconditions, and their usage largely depends on the design style. Class invariants apply to all routines and attributes of a class, and hence they may be used extensively and involve many clauses; conversely, they can also be replaced by pre- and postconditions in most cases, in which case they need not be complex or present at all [40]. In the majority of projects (15 out of 21), however, class invariants have more clauses on average than pre- and postconditions. We might impute this difference to the traditional design principles for objectoriented contract-based programming, which attribute a significant role to class invariants [32,11,46] as the preferred way to define valid object state. In over eighty percent of the projects, the average preconditions contain more clauses than the average postconditions. Section 5.1 observed the prevailing stability over time of routines with specification. Visual inspection and the values of standard deviation point to a qualitatively similar trend for specification size, measured in number of clauses. In the first revisions of a project, it is common to have more varied behavior, corresponding to the system design being defined; but the average strength of specifications typically reaches a plateau, or varies quite slowly, in mature phases. Project Labs is somewhat of an outlier, where the evolution of specification strength over time has a rugged behavior (see [13] for details and plots). Its average number of class invariant clauses has a step at about revision 29, which corresponds to a merge, when it suddenly grows from 1.8 to 2.4 clauses per class. During the few following revisions, however, this figure drops quickly until it reaches a value only slightly higher than what it was before revision 29. What probably happened is that the merge mixed classes developed independently with different programming styles (and, in particular, different attitudes towards the usage of class invariants). Shortly after the merge, the developers refactored the new components to make them comply with the overall style, which is characterized by a certain average invariant strength. One final, qualitative, piece of data about specification strength is that in a few projects there seems to be a moderate increase in the strength of postconditions towards the latest revisions of the project. If this is a real phenomenon, it may show that, as programmers become fluent in writing specification, they are confident enough to go for the more complex postconditions, reversing their initial (moderate) focus on preconditions. This observation is however not applicable to any of the largest and most mature projects we analyzed (e.g., EiffelBase, Boogie, Dafny). The average size (in number of clauses) of specification elements is stable over time.

5.5

Implementation vs. Specification Changes

A phenomenon commonly attributed [42] to specifications is that they are not updated to reflect changes in the implementation: even when programmers deploy specifications 14

extensively in the initial phases of a project, the later become obsolete and, eventually, useless. Is there evidence of such a phenomenon in the data of our projects? We first have to remember a peculiarity of contracts as opposed to other forms of specification. Contracts are executable specifications; normally, they are checked at runtime during debugging and regression testing sessions (and possibly also in production releases, if the overhead is acceptable, to allow for better error reporting from final users). Specifically, most applications and libraries of our study are actively used and maintained. Therefore, their contracts cannot become grossly misaligned with the implementation: inconsistencies quickly generate runtime errors, which can only be fixed by reconciling implementations with their specifications. By and large, the fact that a significant percentage of routines and classes in our study have contracts (Section 5.1) implies that most of them are correct—if incomplete—specifications of routine or class behavior. A natural follow-up question is then whether contracts change more often or less often than the implementations they specify. To answer, we compare two measures in the projects: for each revision, we count the number of routines with changed body and changed specification (pre- or postcondition) and compare it to the number of routines with changed body and unchanged specification. These measures aggregated over all revisions determine a pair of values (cP , uP ) for each project P : cP characterizes the frequency of changes to implementations that also caused a change in the contracts, whereas uP characterizes the frequencies of changes to implementations only. To avoid that few revisions with very many changes dominate the aggregate values for a project, each revision contributes with a binary value to the aggregate value of a project: 0 if no routine has undergone a change of that type in that revision, and 1 otherwise.5 We performed a Wilcoxon signed-rank test comparing the cP ’s to the uP ’s across all projects to determine if the median difference between the two types of events (changed body with and without changed specification) is statistically significant. The results confirm with high statistical significance (V = 0, p = 9.54 · 10−7 , and large effect size—Cohen’s d > 0.99) that specification changes are quite infrequent compared to implementation changes for the same routine. Visual inspection also confirms the same trend: see the last plot in Table 4 about Boogie. A similar analysis ignoring routines with trivial (empty) specification leads to the same conclusion also with statistical significance (V = 29, p = 4.78 · 10−3 , and medium effect size d > 0.5). When specifications do change, what happens to their strength measured in number of clauses? Another Wilcoxon signed-rank test compares the changes to pre- and postconditions and class invariants that added clauses (suggesting strengthening) against those that removed clauses (suggesting weakening). Since changes to specifications are in general infrequent, the results were not as conclusive as those comparing specification and implementation changes. The data consistently points towards strengthening being more frequent than weakening: V = 31.5 and p < 0.02 for precondition changes; V = 29 and p < 0.015 for postcondition changes; V = 58.5 and p = 0.18 for invariant changes. The effect sizes are, however, smallish: Cohen’s d is about 0.4, 0.42, and 0.18 for preconditions, postconditions, and invariants. In all, the effect of strengthening 5

Using other “reasonable” aggregation functions (including exact counting) leads to qualitatively similar results.

15

being more frequent than weakening seems to be real but more data is needed to obtain conclusive evidence. The implementation of an average routine changes much more frequently than its specification. 5.6

Inheritance and Contracts

Inheritance is a principal feature of object-oriented programming, and involves contracts as well as implementations; we now evaluate its effects on the findings previously discussed. We visually inspected the plots and computed correlation coefficients for the percentages and average strength of specified elements in the flat (explicitly including all routines and specification of the ancestor classes) and non-flat (limited to what appears in the class text) versions of the classes. In the overwhelming majority of cases, the correlations are high and statistically significant: 16 projects have τ ≥ 0.54 and p < 10−9 for the percentage of routines with specification; 17 projects have τ ≥ 0.66 and p ∼ 0 for the percentage of classes with invariant; 12 projects have τ ≥ 0.58 and p < 10−7 for the average precondition and postcondition strength (and 7 more projects still have τ ≥ 0.33 and visually evident correlations); and 15 projects have τ ≥ 0.45 and p ∼ 0 for the average invariant strength. The first-order conclusion is that, in most cases, ignoring the inherited specification does not preclude understanding qualitative trends. What about the remaining projects, which have small or insignificant correlations for some of the measures in the flat and non-flat versions? Visual inspection often confirms the absence of significant correlations, in that the measures evolve along manifestly different shapes in the flat or non-flat versions; the divergence in trends is typically apparent in the revisions where the system size changes significantly, where the overall design—and the inheritance hierarchy—is most likely to change. To see if these visible differences invalidate some of the findings discussed so far, we reviewed the findings against the data for flat classes. The big picture was not affected: considering inheritance may affect the measures and offset or bias some trends, but the new measures are still consistent with the same conclusions drawn from the data for nonflat classes. Future work will investigate whether this result is indicative of a mismatch between the semantics of inheritance and how it is used in practice [51,47]. We now discuss the various questions for flat classes in more detail. Qualitative trends of measures involving contracts do not change significantly whether we consider or ignore inherited contracts. Usage (and kinds) of contracts is qualitatively similar for the flat and non-flat classes. Of course, the number of elements with specification tends to be larger in flat classes simply because specifications are inherited. However, the relative magnitude of measures such as the average, minimum, maximum, and standard deviation of routines and classes with specification is quite similar for flat and non-flat. Similar observations hold concerning measures of contract strength and their evolution. Project size is correlated to measures regarding contracts in similar ways in flat and non-flat classes. The few outliers are projects that exhibited a positive correlation between percentage of specified elements and number of elements in the non-flat versions (e.g., τ = 0.66 for EiffelBase); the correlation vanishes in the flat versions (e.g., 16

τ = −0.08 for EiffelBase). As we discussed at the end of Section 5.2, the positive correlations of these outliers were unusual and possibly ephemeral; the fact that correlations dilute away when we consider the inheritance hierarchy reinforces the idea that the positive correlation trends of Section 5.2 are exceptional and largely inconsequential. Java projects are different in that they achieve consistent positive correlations between percentage of specified elements and number of elements in both flat and nonflat versions; there is a simple explanation for this: inheritance hierarchies are shallow in Java projects, and hence inheritance is simply negligible. Change analyses are virtually identical in flat and non-flat classes; this is unsurprising since the analyses (discussed in Section 5.5) target binary differences between a version and the next one, so that the measures gobble up the offset introduced by flattening. Differences between measures with flat and non-flat classes tend to be smaller in C# and Java projects, as opposed to the Eiffel projects. This reveals that multiple inheritance, available in Eiffel but not in C# and Java, may contribute to magnify differences between measures of flat and non-flat classes. (This is also consistent with the observation about shallow inheritance hierarchies in most Java project.)

6

Threats to Validity

Construct validity. The measures taken by C OAT expose two potential threats to construct validity. First, using the number of clauses as a proxy for the strength of a specification may produce imprecise measures; Section 4.3, however, estimated the imprecision and showed it is limited, and hence an acceptable trade-off in most cases (also given that computing strength exactly is infeasible). Besides, the number of clauses is still a valuable size/complexity measure in its own right (Section 5.4). Second, the flattening introduced to study the effect of inheritance (Section 4.2) introduces some approximations when dealing with the most complex usages of multiple inheritance ( select clauses) or of inner classes. We are confident, however, that this approximation has a negligible impact on our measurements as these complex usages occur very rarely. Internal validity. Since we targeted object-oriented languages where inheritance is used pervasively, it is essential that the inheritance structure be taken into account in the measures. We fully addressed this major threat to internal validity by analyzing all projects twice: in non-flat and flat version (Section 5.6). A different threat originates from C OAT failing to parse a few files in some revisions, due to the presence of invalid and outdated language syntax constructs. The impact of this is certainly negligible: less than 0.0069% of all files could not be parsed. Restricting our analysis to the main branches and manually discarding irrelevant content from the repositories pose another potential threat to internal validity. In all cases, we took great care to cover the most prominent development path and to select the main content based on the project configuration files written by the developers, so as to minimize this threat. External validity. Our study is restricted to three formalisms for writing contract specifications: Eiffel, C# with Code Contracts, and Java with JML. While other notations for contracts (e.g., other Java contract libraries or SPARK Ada) are similar, we did 17

not analyze other types of formal specification, which might limit the generalizability of our findings. In contrast, the restriction to open-source projects does not pose a serious threat to external validity in our study, because several of our projects are mainly maintained by professional programmers (EiffelBase and Gobo projects) or by professional researchers in industry (Boogie, CCI, Dafny, and Quickgraph). An important issue to warrant external validity involves the selection of projects. We explicitly targeted projects that make a non-negligible usage of contracts (Section 4.1), as opposed to the overwhelming majority that only include informal documentation or no documentation at all. This deliberate choice limits the generalizability of our findings, but also focuses the study on understanding how contracts can be seriously used in practice. A related observation is that the developers of several of the study’s projects are supporters of using formal specifications. While this is a possible source of bias it also contributes to reliability of the results: since we are analyzing good practices and success stories of writing contracts, we should target competent programmers with sufficient experience, rather than inexpert novices. For the same reason, the most extensive studies on the usage of design patterns (e.g. [48]) target software such as Eclipse— written by experts on design patterns—rather than small student projects or low-quality software. Besides, Schiller et al.’s independent analysis [49] of some C# projects using CodeContracts also included in our study suggests that their developers are hardly fanatic about formal methods, as they use contracts only to the extent that it remains inexpensive and cost-effective, and does not require them to change their programming practices. Nevertheless, to get an idea of whether the programmers we studied really have incomparable skills, we also set up a small control group, consisting of 10 projects developed by students of a software engineering course6 involving students from universities all around the world. The students use Eiffel but usually have limited or no experience with it when starting the course; the selected projects have a development time of circa 6 weeks and numbers of revisions range between 30 to 292. The average size per project is 4185 LOC. All projects were graded good or very good in their final evaluations. We ran the analyses described in this paper on these student projects. In summary (see Section 13 in the Appendix for detailed data), we found that several of the trends measured with the professional programmers were also present in the student projects—albeit on the smaller scale of a course project. This gives some confidence that the big picture outlined by this paper’s results somewhat generalizes to developers willing to spend some programming effort to write contracts and is not limited to “verification wonks” only.

7

Related Work

Section 3 discussed program analysis and other activities where contracts can be useful. To our knowledge, this paper is the first quantitative empirical study of specifications in the form of contracts and their evolution together with code. Schiller et al. [49] study C# projects using CodeContracts (some also part of our study); while our and their results 6

http://se.inf.ethz.ch/research/dose

18

are not directly comparable because we take different measures and classify contract usage differently, the overall qualitative pictures are consistent and nicely complementary. In the paper we also highlighted a few points where their results confirm or justify ours. Schiller et al. do not study contract evolution; there is evidence, however, that other forms of documentation—e.g., comments [15], APIs [25], or tests [58]—evolve with code. A well-known problem is that specification and implementation tend to diverge over time; this is more likely for documents such as requirements and architectural designs that are typically developed and stored separately from the source code. Much research has targeted this problem; specification refinement, for instance, can be applied to software revisions [16]. Along the same lines, some empirical studies analyzed how requirements relate to the corresponding implementations; [22], for example, examines the co-evolution of certain aspects of requirements documents with change logs and shows that topic-based requirements traceability can be automatically implemented from the information stored in version control systems. The information about the usage of formal specification by programmers is largely anecdotal, with the exceptions of a few surveys on industrial practices [5,56]. There is, however, some evidence of the usefulness of contracts and assertions. [28], for example, suggests that increases of assertions density and decreases of fault density correlate. [36] reports that using assertions may decrease the effort necessary for extending existing programs and increase their reliability. In addition, there is evidence that developers are more likely to use contracts in languages that support them natively [5]. As the technology to infer contracts from code reaches high precision levels [12,54], it is natural to compare automatically inferred and programmer-written contracts; they turn out to be, in general, different but with significant overlapping [44]. Our C OAT tool (Section 4.2) is part of a very large family of tools [18] that mine software repositories to extract quantitative data. In particular, it shares some standard technologies with other tools for source code analysis (e.g., [37]).

8

Concluding Discussion & Implications of the Results

Looking at the big picture, our empirical study suggests a few actionable remarks. (i) The effort required to make a quantitatively significant usage of lightweight specifications is sustainable consistently over the lifetime of software projects. This supports the practical applicability of methods and processes that rely on some form of rigorous specification. (ii) The overwhelming majority of contracts that programmers write in practice are short and simple. This means that, to be practical, methods and tools should make the best usage of such simple contracts or acquire more complex and complete specifications by other means (e.g., inference). It also encourages the usage of simple specifications early on in the curriculum and in the training of programmers [27]. (iii) In spite of the simplicity of the contracts that are used in practice, developers who commit to using contracts seem to stick to them over an entire project lifetime. This reveals that even simple specifications bring a value that is worth the effort: a little specification can go a long way. (iv) Developers often seem to adapt their contracts in response to changes in the design; future work in the direction of facilitating these adaptations and making 19

them seamless has a potential for a high impact. (v) A cornerstone software engineering principle—stable interfaces over changing implementations—seems to have been incorporated by programmers. An interesting follow-up question is then whether this principle can be leveraged to improve not only the reusability of software components but also the collaboration between programmers in a development team. (vi) Somewhat surprisingly, inheritance does not seem to affect most qualitative findings of our study. The related important issue of how behavioral subtyping is achieved in practice [47] belongs to future work, together with several other follow-up questions whose answers can build upon the foundations laid by this paper’s results.

9

Conclusions

This paper presented an extensive empirical study of the evolution of specifications in the form of contracts. The study targeted 15 projects written in Eiffel and C# (using Code Contracts) over many years of development. The main results show that the percentages of routines with pre- or postcondition and of classes with invariants is above 33% for most projects; that these percentages tend to be stable over time, if we discount special events like merge or major refactorings; and that specifications change much less often than implementations—which makes a good case for stable interfaces over changing implementations. Acknowledgments. Thanks to Sebastian Nanz for comments on a draft of this paper; and to Todd Schiller, Kellen Donohue, Forrest Coward, and Mike Ernst for sharing a draft of their paper [49] and comments on this work.

References 1. Araujo, W., Briand, L.C., Labiche, Y.: On the effectiveness of contracts as test oracles in the detection and diagnosis of race conditions and deadlocks in concurrent object-oriented software. In: ESEM. pp. 10–19 (2011) 2. Barnett, M., Fähndrich, M., Leino, K.R.M., Müller, P., Schulte, W., Venter, H.: Specification and verification: the Spec# experience. Comm. ACM 54(6), 81–91 (2011) 3. Boyapati, C., Khurshid, S., Marinov, D.: Korat: automated testing based on Java predicates. In: ISSTA. pp. 123–133 (2002) 4. Brun, Y., Holmes, R., Ernst, M.D., Notkin, D.: Proactive detection of collaboration conflicts. In: ESEC/FSE. pp. 168–178 (2011) 5. Chalin, P.: Are practitioners writing contracts? In: The RODIN Book. LNCS, vol. 4157, p. 100 (2006) 6. Cheon, Y., Leavens, G.T.: A simple and practical approach to unit testing: The JML and JUnit way. In: ECOOP. pp. 231–255 (2002) 7. http://se.inf.ethz.ch/data/coat/ 8. http://research.microsoft.com/en-us/projects/contracts/ 9. Curino, C., Moon, H.J., Zaniolo, C.: Graceful database schema evolution: the prism workbench. PVLDB 1(1), 761–772 (2008) 10. Dietl, W., Dietzel, S., Ernst, M.D., Muslu, K., Schiller, T.W.: Building and using pluggable type-checkers. In: ICSE. pp. 681–690. ACM (2011)

20

11. Drossopoulou, S., Francalanza, A., Müller, P., Summers, A.J.: A unified framework for verification techniques for object invariants. In: ECOOP 2008 – Object-Oriented Programming. pp. 412–437. Lecture Notes in Computer Science, Springer (2008) 12. Ernst, M.D., Perkins, J.H., Guo, P.J., McCamant, S., Pacheco, C., Tschantz, M.S., Xiao, C.: The Daikon system for dynamic detection of likely invariants. Sci. Comput. Program. 69, 35–45 (2007) 13. Estler, H.C., Furia, C.A., Nordio, M., Piccioni, M., Meyer, B.: Contracts in practice. http: //arxiv.org/abs/1211.4775 (2013), extended version with appendix 14. Fähndrich, M., Barnett, M., Logozzo, F.: Embedded contract languages. In: SAC. pp. 2103– 2110. ACM (2010) 15. Fluri, B., Würsch, M., Gall, H.: Do code and comments co-evolve? on the relation between source code and comment changes. In: WCRE. pp. 70–79. IEEE (2007) 16. García-Duque, J., Pazos-Arias, J., López-Nores, M., Blanco-Fernández, Y., Fernández-Vilas, A., Díaz-Redondo, R., Ramos-Cabrer, M., Gil-Solla, A.: Methodologies to evolve formal specifications through refinement and retrenchment in an analysis-revision cycle. Requirements Engineering 14, 129–153 (2009) 17. Gaudel, M.C.: Software testing based on formal specification. In: Testing Techniques in Software Engineering. Lecture Notes in Computer Science, vol. 6153, pp. 215–242. Springer (2007) 18. Germán, D.M., Cubranic, D., Storey, M.A.D.: A framework for describing and understanding mining tools in software development. In: MSR (2005) 19. Harman, M., Kim, S.G., Lakhotia, K., McMinn, P., Yoo, S.: Optimizing for the number of tests generated in search based test data generation with an application to the oracle cost problem. In: ICST Workshops. pp. 182–191 (2010) 20. Henkel, J., Reichenbach, C., Diwan, A.: Discovering documentation for Java container classes. IEEE Trans. Software Eng. 33(8), 526–543 (2007) 21. Hierons, R.M., Bogdanov, K., Bowen, J.P., Cleaveland, R., Derrick, J., Dick, J., Gheorghe, M., Harman, M., Kapoor, K., Krause, P., Lüttgen, G., Simons, A.J.H., Vilkomir, S.A., Woodward, M.R., Zedan, H.: Using formal specifications to support testing. ACM Comput. Surv. 41(2) (2009) 22. Hindle, A., Bird, C., Zimmermann, T., Nagappan, N.: Relating requirements to implementation via topic analysis. In: ICSM (2012) 23. Jiang, Y., Hou, S.S., Shan, J., Zhang, L., Xie, B.: An approach to testing black-box components using contract-based mutation. International Journal of Software Engineering and Knowledge Engineering 18(1), 93–117 (2008) 24. http://www.jmlspecs.org 25. Kim, M., Cai, D., Kim, S.: An empirical investigation into the role of API-level refactorings during software evolution. In: ICSE. pp. 151–160. ACM (2011) 26. http://kindsoftware.com 27. Kiniry, J.R., Zimmerman, D.M.: Secret ninja formal methods. In: FM. LNCS, vol. 5014, pp. 214–228. Springer (2008) 28. Kudrjavets, G., Nagappan, N., Ball, T.: Assessing the relationship between software assertions and faults: An empirical investigation. In: ISSRE. pp. 204–212 (2006) 29. Leavens, G.T., Baker, A.L., Ruby, C.: JML: A notation for detailed design. In: Behavioral Specifications of Businesses and Systems, pp. 175–188. Kluwer Academic Publishers (1999) 30. Marinov, D., Khurshid, S.: TestEra: A novel framework for automated testing of Java programs. In: ASE. p. 22 (2001) 31. Martin, J.K., Hirschberg, D.S.: Small sample statistics for classification error rates II. Tech. rep., CS Department, UC Irvine (1996), http://goo.gl/Ec8oD 32. Meyer, B.: Object Oriented Software Construction. Prentice Hall PTR, 2 edn. (1997)

21

33. Meyer, B., Fiva, A., Ciupa, I., Leitner, A., Wei, Y., Stapf, E.: Programs that test themselves. Computer 42(9), 46–55 (2009) 34. Meyer, B., Kogtenkov, A., Stapf, E.: Avoid a Void: the eradication of null dereferencing. In: Reflections on the Work of C.A.R. Hoare, pp. 189–211. Springer (2010) 35. Monk, S.R., Sommerville, I.: Schema evolution in OODBs using class versioning. SIGMOD Record 22(3), 16–22 (1993) 36. Müller, M.M., Typke, R., Hagner, O.: Two controlled experiments concerning the usefulness of assertions as a means for programming. In: ICSM. pp. 84–92 (2002) 37. Neamtiu, I., Foster, J.S., Hicks, M.W.: Understanding source code evolution using abstract syntax tree matching. In: MSR (2005) 38. Nordio, M., Estler, H.C., Furia, C.A., Meyer, B.: Collaborative software development on the web. http://arxiv.org/abs/1105.0768 (September 2011) 39. http://openjml.org 40. Parkinson, M.: Class invariants: The end of the road? (position paper) (2007) 41. Parnas, D.L.: On the criteria to be used in decomposing systems into modules. Commun. ACM 15(12), 1053–1058 (1972) 42. Parnas, D.L.: Precise documentation: The key to better software. In: The Future of Software Engineering. pp. 125–148. Springer (2011) 43. Piccioni, M., Oriol, M., Meyer, B.: Class schema evolution for persistent object-oriented software: Model, empirical study, and automated support. IEEE TSE (2012), to appear 44. Polikarpova, N., Ciupa, I., Meyer, B.: A comparative study of programmer-written and automatically inferred contracts. In: ISSTA. pp. 93–104 (2009) 45. Polikarpova, N., Furia, C.A., Pei, Y., Wei, Y., Meyer, B.: What good are strong specifications? In: ICSE. pp. 257–266. ACM (2013) 46. Polikarpova, N., Tschannen, J., Furia, C.A., Meyer, B.: Flexible invariants through semantic collaboration. In: FM. LNCS, Springer (2014) 47. Pradel, M., Gross, T.R.: Automatic testing of sequential and concurrent substitutability. In: ICSE. pp. 282–291. ACM (2013) 48. Ricca, F., Penta, M.D., Torchiano, M., Tonella, P., Ceccato, M.: How design notations affect the comprehension of Web applications. Journal of Software Maintenance 19(5), 339–359 (2007) 49. Schiller, T.W., Donohue, K., Coward, F., Ernst, M.D.: Writing and enforcing contract specifications. In: ICSE. ACM (2014) 50. Staats, M., Whalen, M.W., Heimdahl, M.P.E.: Programs, tests, and oracles. In: ICSE. pp. 391–400 (2011) 51. Tempero, E.D., Yang, H.Y., Noble, J.: What programmers do with inheritance in Java. In: ECOOP. Lecture Notes in Computer Science, vol. 7920, pp. 577–601. Springer (2013) 52. Tillmann, N., de Halleux, J.: Pex–White box test generation for .NET. In: TAP. pp. 134–153 (2008) 53. Wasylkowski, A., Zeller, A.: Mining temporal specifications from object usage. Autom. Softw. Eng. 18(3-4), 263–292 (2011) 54. Wei, Y., Furia, C.A., Kazmin, N., Meyer, B.: Inferring better contracts. In: ICSE. pp. 191–200 (2011) 55. Wei, Y., Roth, H., Furia, C.A., Pei, Y., Horton, A., Steindorfer, M., Nordio, M., Meyer, B.: Stateful testing: Finding more errors in code and contracts. In: ASE. IEEE (2011) 56. Woodcock, J., Larsen, P.G., Bicarregui, J., Fitzgerald, J.: Formal methods: Practice and experience. ACM CSUR 41(4) (2009) 57. Xie, T.: Augmenting automatically generated unit-test suites with regression oracle checking. In: ECOOP. Lecture Notes in Computer Science, vol. 4067, pp. 380–403. Springer (2006) 58. Zaidman, A., Van Rompaey, B., Demeyer, S., van Deursen, A.: Mining software repositories to study co-evolution of production and test code. In: ICST. pp. 220 –229 (2008)

22

59. Zimmerman, D.M., Nagmoti, R.: JMLUnit: The next generation. In: FoVeOOS. LNCS, vol. 6528, pp. 183–197. Springer (2010)

23

# CLASSES m µ M σ 98 220 254 66 93 184 256 36 0 179 221 30 0 72 157 38 42 75 109 17 0 22 47 10 3 25 43 10 0 176 859 252 9 606 647 181 45 60 108 15 11 148 184 25 47 58 75 8 228 260 336 27 0 145 189 53 0 28 36 13 13 55 82 17 66 161 308 80 107 124 641 29 20 22 23 1 48 142 144 42 23 41 77 16

% CLASSES INV m µ M σ 0.38 0.43 0.55 0.06 0.24 0.34 0.39 0.03 0 0.04 0.05 0 0 0.11 0.13 0.04 0.19 0.33 0.39 0.06 0 0.12 0.28 0.09 0 0.22 0.5 0.08 0 0.38 0.48 0.07 0.24 0.34 0.58 0.06 0.01 0.04 0.06 0.01 0.04 0.47 0.52 0.06 0.35 0.38 0.42 0.02 0 0.02 0.04 0.01 0 0.42 0.44 0.08 0 0 0 0 0 0 0.03 0 0.11 0.17 0.26 0.05 0.12 0.47 0.62 0.04 0.04 0.09 0.09 0.01 0.08 0.1 0.11 0.01 0 0.06 0.1 0.03 m 352 545 0 0 122 0 1 0 80 160 25 351 1074 0 0 74 233 499 154 359 36

# ROUTINES µ M σ 1053 1234 372 1984 3323 696 828 1127 199 168 702 155 372 483 88 176 333 53 90 185 55 883 5465 1603 3542 3748 1055 210 302 50 375 551 85 413 518 29 1262 1862 179 1358 1792 494 57 85 33 440 582 115 585 3079 853 589 1081 125 171 173 6 441 447 35 122 332 78

% ROUTINES SPEC m µ M σ 0.47 0.49 0.61 0.06 0.26 0.4 0.44 0.04 0 0.25 0.27 0.02 0 0.6 1 0.17 0.18 0.29 0.41 0.07 0 0.63 0.66 0.06 0 0.9 0.98 0.14 0 0.35 0.44 0.05 0.49 0.52 0.81 0.09 0 0.03 0.05 0.01 0.16 0.64 0.74 0.07 0.38 0.47 0.5 0.03 0 0.16 0.22 0.07 0 0.7 0.97 0.11 0 0.1 0.4 0.07 0.06 0.15 0.37 0.04 0.16 0.36 0.74 0.21 0.34 0.43 0.8 0.15 0.32 0.49 0.54 0.04 0.06 0.56 0.59 0.24 0 0.02 0.05 0.02

% ROUTINES PRE m µ M σ 0.23 0.25 0.4 0.07 0.17 0.27 0.3 0.03 0 0.14 0.16 0.02 0 0.3 0.4 0.09 0.07 0.19 0.28 0.06 0 0.28 0.33 0.03 0 0.58 0.83 0.12 0 0.23 0.35 0.03 0.28 0.3 0.74 0.13 0 0.03 0.04 0.01 0.16 0.57 0.64 0.06 0.28 0.38 0.42 0.03 0 0.15 0.21 0.07 0 0.6 0.93 0.13 0 0.1 0.4 0.07 0.06 0.15 0.37 0.04 0.14 0.27 0.69 0.2 0.26 0.34 0.74 0.14 0.14 0.33 0.35 0.04 0.03 0.07 0.1 0.02 0 0.01 0.03 0.01

% ROUTINES POST m µ M σ 0.34 0.36 0.45 0.04 0.14 0.24 0.26 0.03 0 0.15 0.16 0.01 0 0.51 1 0.19 0.16 0.23 0.32 0.05 0 0.58 0.6 0.06 0 0.58 0.67 0.11 0 0.23 0.33 0.06 0.08 0.32 0.38 0.04 0 0 0.01 0 0 0.18 0.22 0.03 0.1 0.13 0.21 0.03 0 0.01 0.02 0.01 0 0.62 0.81 0.08 0 0.01 0.07 0.02 0.02 0.1 0.35 0.05 0.06 0.12 0.2 0.03 0.13 0.18 0.31 0.04 0.21 0.28 0.33 0.02 0.04 0.52 0.54 0.23 0 0.02 0.04 0.01

200

400

800

revision

600

1000

1200 inv

pre post0 50

100 revision

150

200

250

300

AutoTest: % routines and classes with specification

# clauses per routine or class

% routines or classes

0.40

m 1.73 1.43 0 0 1.45 0 0 0 1.6 1 1 1.34 0 0 0 1 1.07 1.2 1.39 1.21 0

µ 1.76 1.6 1.23 2.1 1.82 1.62 1.8 1.43 1.73 1.33 2.29 1.37 1.71 2.1 1.6 1 1.27 1.54 1.43 1.28 1

M 1.85 1.7 1.25 2.91 1.93 1.7 2.07 1.55 1.76 1.6 2.36 1.58 2.1 2.24 2 1.33 1.66 1.61 1.5 1.36 1

σ 0.03 0.05 0.09 0.59 0.13 0.15 0.24 0.14 0.03 0.22 0.18 0.08 0.71 0.18 0.77 0.05 0.21 0.12 0.04 0.04 0.49

m 1.19 1.2 0 0 1.17 0 0 0 1 0 0 1.13 0 0 0 1 1.21 1.26 1.58 1 0

µ 1.22 1.46 1.13 1.32 1.44 2.28 1.29 1.2 1.02 0 1.04 1.17 1.18 1.03 1 1 1.52 1.48 1.75 1.04 1

M 1.28 1.51 1.17 1.86 1.49 2.53 1.52 1.36 1.02 1 1.05 1.28 1.36 1.12 1 1 1.88 1.82 2 1.05 1

inv

pre 0 post

200

revision

400

600

800

ESCJava: Specification clauses per routine or class

spec only

body+spec body only200

400 revision

600

800

Boogie: # changed routines or spec

σ 0.03 0.06 0.08 0.25 0.1 0.25 0.25 0.07 0.01 0.49 0.14 0.05 0.46 0.1 0.49 0 0.12 0.09 0.08 0.02 0.47

AVG ROUTINES PRE AVG ROUTINES POST

Table 4. Selected plots for projects EiffelBase, AutoTest, ESCJava, and Boogie. Each graph from left to right represents the evolution over successive revisions of: (1) and (2), percentage of routines with precondition (pre in the legend), with postcondition (post), and of classes with invariant (inv); (3), average number of clauses in contracts; (4), number of changes to implementation and specification (body+spec), to implementation only (body only), and change to specification only. When present, a thin gray line plots the total number of routine in the project (scaled). Similar plots for all projects are available [13,7].

inv

pre post0

EiffelBase: % routines and classes with specification

# routines

Table 3. Specification overall statistics with non-flat classes. For each project, we report the number of classes and of public routines (# CLASSES, # ROUTINES); the percentage (1 is 100%) of classes with non-empty invariant (% CLASSES INV); of routines with non-empty specification (% ROU TINES SPEC ) and more specifically with non-empty precondition ( PRE ) and postcondition ( POST); the mean number of clauses of routine preconditions (AVG ROUTINES PRE) and of postconditions (POST). For each measure, the table reports minimum (m), median (µ), maximum (M), and standard deviation (σ) across all revisions.

Project AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny Labs Quickgraph Rxx Shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra

% routines or classes

0.35

0.30

0.25

0.20

0.15

0.55 0.50 0.45 0.40 0.35 0.30 0.25

0.8 0.6 0.4 0.2

150 100 50 0

24

10

Appendix: Complete Statistics

This appendix contains several tables with all statistics discussed in the paper. In all tables, the few missing data about project Shweet are due to the fact that the project lacks class invariants, and hence the corresponding statistics are immaterial. General specification statistics. Table 95 lists various general statistics about specifications: # of classes, % of classes with invariant, # of routines, % of routines with specification (pre- or postcondition), % of routines with precondition, % of routines with postcondition, average number of clauses in preconditions, average number of clauses in postconditions, average number of clauses in class invariants. Table 96 lists the same data but for flat classes. Table 97 lists other statistics about projects: language, number of revisions, age in weeks, lines of code, and then some of the same statistics about classes and routines as in Table 95. Table 98 lists the same data for flat classes. Change correlation analysis. Table 99 lists Wilcoxon signed-rank tests about changes, as described in Section 5.5, comparing: changing and non-changing specifications of routines whose body changes; changing and non-changing NE (i.e., non-empty) specifications of routines whose body changes; preconditions becoming weaker vs. becoming stronger, NE preconditions becoming weaker vs. becoming stronger, postconditions becoming weaker vs. becoming stronger, NE postconditions becoming weaker vs. becoming stronger, class invariants becoming weaker vs. becoming stronger, NE class invariants becoming weaker vs. becoming stronger, class invariants becoming weaker when attributes are added vs. it not changing in strength; class invariants becoming stronger when attributes are added vs. it not changing in strength; class invariants becoming weaker when attributes are removed vs. it not changing in strength; class invariants becoming stronger when attributes are removed vs. it not changing in strength. The statistics are V and p from the signed-rank test; ∆(µ) is the difference in medians, whose value is positive iff the first—between the two compared measures—median is larger; d is Cohen’s effect size ((m1 − m2 )/σ where m1 , m2 are the means of the two compared measures and σ is the standard deviation of the whole measured data), whose value is positive iff the first—between the two compared measures—mean is larger. The top half of the table considers non-flat classes, whereas the bottom half considers flat classes. Table 100 shows the results of the same analysis but done by summing all changes instead of counting them with a binary value for each revision (see Section 5.5). Flat vs. non-flat correlation analysis. Table 101 lists correlation statistics between the evolution of the following measures in flat and non-flat classes: % of routines with specification; % of classes with invariants; average number of precondition clauses; average number of postcondition clauses, average number of invariant clauses. Size correlation analysis. Table 102 lists correlation statistics between several pair of measures: % of routines with specification and total # of routines; # of routines with specification and total # of routines; % of classes with invariant and total # of classes; # of classes with invariant and total # of classes, average number of precondition clauses and % of routines with precondition; average number of postcondition clauses and % of routines with postcondition; average number of invariant clauses and % of classes with invariants. Table 103 lists the same statistics for flat classes. 25

Public vs. non-public correlation analysis. Table 104 lists correlation statistics between: % of public routines with precondition and % of non-public routines with precondition; % of public routines with postcondition and % of non-public routines with postcondition; % of public routines with specification and % of non-public routines with specification. Table 105 lists the same statistics for flat classes. Kinds of constructs. Table 106 lists statistics about constructs used in contracts: % of preconditions with Void or null checks; % of preconditions with some form of quantification; % of postconditions with Void or null checks; % of postconditions with some form of quantification; % of postconditions with old; % of class invariants with Void or null checks; % of class invariants with some form of quantification.

26

# CLASSES % CLASSES INV # ROUTINES Project m µ M σ m µ M σ m µ M AutoTest 98 220 254 66 0.38 0.43 0.55 0.06 352 1053 1234 EiffelBase 93 184 256 36 0.24 0.34 0.39 0.03 545 1984 3323 EiffelProgramAnalysis 0 179 221 30 0 0.04 0.05 0 0 828 1127 GoboKernel 0 72 157 38 0 0.11 0.13 0.04 0 168 702 GoboStructure 42 75 109 17 0.19 0.33 0.39 0.06 122 372 483 GoboTime 0 22 47 10 0 0.12 0.28 0.09 0 176 333 GoboUtility 3 25 43 10 0 0.22 0.5 0.08 1 90 185 GoboXML 0 176 859 252 0 0.38 0.48 0.07 0 883 5465 Boogie 9 606 647 181 0.24 0.34 0.58 0.06 80 3542 3748 CCI 45 60 108 15 0.01 0.04 0.06 0.01 160 210 302 Dafny 11 148 184 25 0.04 0.47 0.52 0.06 25 375 551 Labs 47 58 75 8 0.35 0.38 0.42 0.02 351 413 518 Quickgraph 228 260 336 27 0 0.02 0.04 0.01 1074 1262 1862 Rxx 0 145 189 53 0 0.42 0.44 0.08 0 1358 1792 shweet 0 28 36 13 0 0 0 0 0 57 85 DirectVCGen 13 55 82 17 0 0 0.03 0 74 440 582 ESCJava 66 161 308 80 0.11 0.17 0.26 0.05 233 585 3079 JavaFE 107 124 641 29 0.12 0.47 0.62 0.04 499 589 1081 Logging 20 22 23 1 0.04 0.09 0.09 0.01 154 171 173 RCC 48 142 144 42 0.08 0.1 0.11 0.01 359 441 447 Umbra 23 41 77 16 0 0.06 0.1 0.03 36 122 332 σ 372 696 199 155 88 53 55 1603 1055 50 85 29 179 494 33 115 853 125 6 35 78

% ROUTINES SPEC m µ M σ 0.47 0.49 0.61 0.06 0.26 0.4 0.44 0.04 0 0.25 0.27 0.02 0 0.6 1 0.17 0.18 0.29 0.41 0.07 0 0.63 0.66 0.06 0 0.9 0.98 0.14 0 0.35 0.44 0.05 0.49 0.52 0.81 0.09 0 0.03 0.05 0.01 0.16 0.64 0.74 0.07 0.38 0.47 0.5 0.03 0 0.16 0.22 0.07 0 0.7 0.97 0.11 0 0.1 0.4 0.07 0.06 0.15 0.37 0.04 0.16 0.36 0.74 0.21 0.34 0.43 0.8 0.15 0.32 0.49 0.54 0.04 0.06 0.56 0.59 0.24 0 0.02 0.05 0.02

% ROUTINES PRE m µ M σ 0.23 0.25 0.4 0.07 0.17 0.27 0.3 0.03 0 0.14 0.16 0.02 0 0.3 0.4 0.09 0.07 0.19 0.28 0.06 0 0.28 0.33 0.03 0 0.58 0.83 0.12 0 0.23 0.35 0.03 0.28 0.3 0.74 0.13 0 0.03 0.04 0.01 0.16 0.57 0.64 0.06 0.28 0.38 0.42 0.03 0 0.15 0.21 0.07 0 0.6 0.93 0.13 0 0.1 0.4 0.07 0.06 0.15 0.37 0.04 0.14 0.27 0.69 0.2 0.26 0.34 0.74 0.14 0.14 0.33 0.35 0.04 0.03 0.07 0.1 0.02 0 0.01 0.03 0.01

% ROUTINES POST m µ M σ 0.34 0.36 0.45 0.04 0.14 0.24 0.26 0.03 0 0.15 0.16 0.01 0 0.51 1 0.19 0.16 0.23 0.32 0.05 0 0.58 0.6 0.06 0 0.58 0.67 0.11 0 0.23 0.33 0.06 0.08 0.32 0.38 0.04 0 0 0.01 0 0 0.18 0.22 0.03 0.1 0.13 0.21 0.03 0 0.01 0.02 0.01 0 0.62 0.81 0.08 0 0.01 0.07 0.02 0.02 0.1 0.35 0.05 0.06 0.12 0.2 0.03 0.13 0.18 0.31 0.04 0.21 0.28 0.33 0.02 0.04 0.52 0.54 0.23 0 0.02 0.04 0.01

µ 1.76 1.6 1.23 2.1 1.82 1.62 1.8 1.43 1.73 1.33 2.29 1.37 1.71 2.1 1.6 1 1.27 1.54 1.43 1.28 1

M 1.85 1.7 1.25 2.91 1.93 1.7 2.07 1.55 1.76 1.6 2.36 1.58 2.1 2.24 2 1.33 1.66 1.61 1.5 1.36 1

σ 0.03 0.05 0.09 0.59 0.13 0.15 0.24 0.14 0.03 0.22 0.18 0.08 0.71 0.18 0.77 0.05 0.21 0.12 0.04 0.04 0.49

AVG ROUTINES PRE

m 1.73 1.43 0 0 1.45 0 0 0 1.6 1 1 1.34 0 0 0 1 1.07 1.2 1.39 1.21 0

Table 5. Specification overall statistics with non-flattened classes.

µ 1.22 1.46 1.13 1.32 1.44 2.28 1.29 1.2 1.02 0 1.04 1.17 1.18 1.03 1 1 1.52 1.48 1.75 1.04 1

M 1.28 1.51 1.17 1.86 1.49 2.53 1.52 1.36 1.02 1 1.05 1.28 1.36 1.12 1 1 1.88 1.82 2 1.05 1

σ 0.03 0.06 0.08 0.25 0.1 0.25 0.25 0.07 0.01 0.49 0.14 0.05 0.46 0.1 0.49 0 0.12 0.09 0.08 0.02 0.47

AVG ROUTINES POST

m 1.19 1.2 0 0 1.17 0 0 0 1 0 0 1.13 0 0 0 1 1.21 1.26 1.58 1 0

m 2.76 2.08 0 0 1.78 0 0 0 2.6 1 1 1.76 0 0 0 0 2.59 3.87 1 4.5 0

M 3.51 2.62 1.33 2 3.54 3.27 5.8 2.49 5.32 2 2.94 2.38 2.14 9 0 2 3.56 5.03 2 6 2.25

AVG INV

µ 3.07 2.3 1.17 1.44 2.88 2.5 3.82 2.1 3.14 1 2.8 1.9 2 3.16 0 0 2.77 4.37 1 4.5 1.75

σ 0.22 0.13 0.12 0.41 0.48 0.41 1.12 0.38 0.45 0.35 0.25 0.15 0.75 1.12 0 0.1 0.25 0.26 0.26 0.54 0.82

27

28

µ 1.13 1.49 1.13 1.43 1.53 2.21 1.19 1.13 1.02 0 1.01 1.12 1.18 1.03 1 1 1.44 1.44 1.75 1.02 1

M 1.21 1.53 1.59 1.66 1.61 2.51 1.37 1.3 1.03 1 1.02 1.19 1.36 1.12 1 1 1.74 4.59 2 1.03 1

σ 0.04 0.04 0.17 0.24 0.04 0.26 0.2 0.07 0.01 0.49 0.14 0.03 0.46 0.09 0.49 0 0.11 0.41 0.08 0.01 0.47

AVG ROUTINES POST

σ 0.03 0.03 0.11 0.65 0.13 0.18 0.19 0.12 0.05 0.22 0.16 0.08 0.71 0.18 0.77 0.05 0.19 0.06 0.04 0.04 0.49

m 1.11 1.27 0 0 1.46 0 0 0 1 0 0 1.09 0 0 0 1 1.15 1.32 1.58 1 0

M 1.82 1.45 1.34 3.31 1.95 1.7 2.07 1.54 1.76 1.6 2.21 1.44 2.1 2.24 2 1.33 1.61 1.48 1.5 1.37 1

m 1.7 1.3 0 0 1.42 0 0 0 1.49 1 1 1.17 0 0 0 1 1.06 1.23 1.39 1.23 0

µ 1.74 1.38 1.16 2.26 1.61 1.61 1.7 1.34 1.51 1.33 2.09 1.19 1.71 2.01 1.6 1 1.23 1.42 1.43 1.31 1

AVG ROUTINES PRE

Table 6. Specification overall statistics with flattened classes.

# CLASSES % CLASSES INV # ROUTINES % ROUTINES SPEC % ROUTINES PRE % ROUTINES POST Project m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ AutoTest 98 220 254 66 0.48 0.54 0.63 0.05 524 2395 2946 1005 0.58 0.6 0.77 0.06 0.37 0.39 0.48 0.04 0.38 0.41 0.59 0.06 EiffelBase 93 184 256 36 0.49 0.66 0.69 0.04 1377 5214 7542 1326 0.54 0.68 0.69 0.03 0.38 0.48 0.49 0.02 0.3 0.45 0.49 0.03 EiffelProgramAnalysis 0 179 221 30 0 0.07 0.08 0.01 0 5300 8360 2064 0 0.2 0.25 0.03 0 0.11 0.18 0.03 0 0.1 0.13 0.02 GoboKernel 0 72 157 38 0 0.12 0.29 0.04 0 271 1304 308 0 0.84 1 0.15 0 0.49 0.6 0.16 0 0.62 1 0.18 GoboStructure 42 75 109 17 0.5 0.81 0.87 0.11 245 1421 2900 696 0.7 0.83 0.91 0.04 0.51 0.57 0.74 0.05 0.53 0.61 0.76 0.06 GoboTime 0 22 47 10 0 0.18 0.38 0.1 0 346 630 87 0 0.85 0.88 0.08 0 0.46 0.53 0.05 0 0.69 0.73 0.07 GoboUtility 3 25 43 10 0 0.52 0.57 0.09 1 118 221 62 0 0.91 0.99 0.12 0 0.5 0.83 0.09 0 0.68 0.72 0.12 GoboXML 0 176 859 252 0 0.63 0.8 0.13 0 2326 113813 35183 0 0.67 0.77 0.09 0 0.49 0.67 0.08 0 0.4 0.52 0.11 Boogie 9 606 647 181 0.24 0.34 0.58 0.06 80 7032 7894 2249 0.63 0.65 0.8 0.05 0.5 0.5 0.74 0.06 0.08 0.43 0.48 0.06 CCI 45 60 108 15 0.01 0.04 0.06 0.01 163 214 309 52 0 0.03 0.05 0.01 0 0.03 0.04 0.01 0 0 0.01 0 Dafny 11 148 184 25 0.04 0.47 0.52 0.06 25 886 1515 309 0.16 0.62 0.72 0.09 0.16 0.46 0.53 0.06 0 0.27 0.35 0.06 Labs 47 58 75 8 0.35 0.38 0.42 0.02 684 790 941 51 0.31 0.49 0.53 0.06 0.19 0.37 0.43 0.06 0.12 0.16 0.19 0.02 Quickgraph 228 260 336 27 0 0.02 0.04 0.01 1075 1263 1863 179 0 0.16 0.22 0.07 0 0.15 0.21 0.07 0 0.01 0.02 0.01 Rxx 0 145 189 53 0 0.42 0.44 0.08 0 1448 2686 777 0 0.77 0.98 0.1 0 0.69 0.95 0.11 0 0.72 0.86 0.08 shweet 0 28 36 13 0 0 0 0 0 67 100 39 0 0.09 0.4 0.07 0 0.08 0.4 0.07 0 0.01 0.07 0.01 DirectVCGen 13 55 82 17 0 0 0.03 0 274 680 1199 200 0.02 0.11 0.18 0.02 0.02 0.11 0.18 0.02 0.01 0.08 0.18 0.03 ESCJava 66 161 308 80 0.11 0.17 0.26 0.05 304 746 3819 1130 0.17 0.42 0.76 0.21 0.13 0.25 0.68 0.2 0.08 0.14 0.35 0.04 JavaFE 107 124 641 29 0.12 0.47 0.62 0.04 815 980 1761 176 0.37 0.45 0.74 0.12 0.3 0.38 0.67 0.11 0.18 0.22 0.31 0.03 Logging 20 22 23 1 0.04 0.09 0.09 0.01 154 171 173 6 0.32 0.49 0.54 0.04 0.14 0.33 0.35 0.04 0.21 0.28 0.33 0.02 RCC 48 142 144 42 0.08 0.1 0.11 0.01 798 952 959 66 0.04 0.69 0.7 0.31 0.02 0.04 0.05 0.01 0.04 0.67 0.67 0.3 Umbra 23 41 77 16 0 0.06 0.1 0.03 335 612 1466 355 0 0.03 0.06 0.02 0 0.02 0.05 0.02 0 0.01 0.02 0.01

m 3.42 6.75 0 0 3.67 0 0 0 2.6 1 1 2.63 0 0 0 0 3.04 4.55 1 4.5 0

AVG INV

µ M σ 3.58 3.81 0.14 10.8 13.27 1.16 1.1 1.21 0.1 1.4 2 0.41 6.74 8.61 1.32 2.33 5.13 1.17 3 3.36 0.58 2.92 8.96 2.49 3.79 5.66 0.44 1 2 0.35 3.71 4.14 0.41 3.14 3.4 0.19 2 2.14 0.75 3.16 9 1.12 0 0 0 0 2 0.1 3.58 5.57 0.26 4.96 6 0.39 1 2 0.26 4.5 6 0.54 3.75 6.25 2.22

Project AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny Labs Quickgraph Rxx shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra

lang Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel C# C# C# C# C# C# C# Java Java Java Java Java Java

rev 306 1342 208 671 282 120 215 922 766 100 326 49 380 148 59 376 879 395 29 30 153

age 195 1006 114 747 716 524 716 285 108 171 106 30 100 68 7 119 366 389 106 350 169

m 17154 13154 0 0 3995 0 188 0 1831 6352 847 10296 22421 32 37 1113 15070 22813 4965 9362 2136

LOC µ M 52958 65625 45200 61922 27498 40750 8457 53316 13069 21941 4131 10840 3591 6131 24146 163552 83444 88284 8358 20602 21700 29700 12141 14540 30343 40820 41616 55932 1741 2352 9550 13294 42055 73760 24993 35013 5751 5963 10688 10872 7549 15538 σ 19291 11922 8546 9175 4525 1753 1816 48763 23486 2834 4709 1002 4767 15998 887 3645 17731 2634 254 531 3723

# CLASSES m µ M σ 98 220 254 66 93 184 256 36 0 179 221 30 0 72 157 38 42 75 109 17 0 22 47 10 3 25 43 10 0 176 859 252 9 606 647 181 45 60 108 15 11 148 184 25 47 58 75 8 228 260 336 27 0 145 189 53 0 28 36 13 13 55 82 17 66 161 308 80 107 124 641 29 20 22 23 1 48 142 144 42 23 41 77 16

% CLASSES INV m µ M σ 0.38 0.43 0.55 0.06 0.24 0.34 0.39 0.03 0 0.04 0.05 0 0 0.11 0.13 0.04 0.19 0.33 0.39 0.06 0 0.12 0.28 0.09 0 0.22 0.5 0.08 0 0.38 0.48 0.07 0.24 0.34 0.58 0.06 0.01 0.04 0.06 0.01 0.04 0.47 0.52 0.06 0.35 0.38 0.42 0.02 0 0.02 0.04 0.01 0 0.42 0.44 0.08 0 0 0 0 0 0 0.03 0 0.11 0.17 0.26 0.05 0.12 0.47 0.62 0.04 0.04 0.09 0.09 0.01 0.08 0.1 0.11 0.01 0 0.06 0.1 0.03

m 352 545 0 0 122 0 1 0 80 160 25 351 1074 0 0 74 233 499 154 359 36

# ROUTINES µ M σ 1053 1234 372 1984 3323 696 828 1127 199 168 702 155 372 483 88 176 333 53 90 185 55 883 5465 1603 3542 3748 1055 210 302 50 375 551 85 413 518 29 1262 1862 179 1358 1792 494 57 85 33 440 582 115 585 3079 853 589 1081 125 171 173 6 441 447 35 122 332 78

% ROUTINES SPEC m µ M σ 0.47 0.49 0.61 0.06 0.26 0.4 0.44 0.04 0 0.25 0.27 0.02 0 0.6 1 0.17 0.18 0.29 0.41 0.07 0 0.63 0.66 0.06 0 0.9 0.98 0.14 0 0.35 0.44 0.05 0.49 0.52 0.81 0.09 0 0.03 0.05 0.01 0.16 0.64 0.74 0.07 0.38 0.47 0.5 0.03 0 0.16 0.22 0.07 0 0.7 0.97 0.11 0 0.1 0.4 0.07 0.06 0.15 0.37 0.04 0.16 0.36 0.74 0.21 0.34 0.43 0.8 0.15 0.32 0.49 0.54 0.04 0.06 0.56 0.59 0.24 0 0.02 0.05 0.02

Table 7. Project specification statistics for non-flattened classes.

% ROUTINES PRE m µ M σ 0.23 0.25 0.4 0.07 0.17 0.27 0.3 0.03 0 0.14 0.16 0.02 0 0.3 0.4 0.09 0.07 0.19 0.28 0.06 0 0.28 0.33 0.03 0 0.58 0.83 0.12 0 0.23 0.35 0.03 0.28 0.3 0.74 0.13 0 0.03 0.04 0.01 0.16 0.57 0.64 0.06 0.28 0.38 0.42 0.03 0 0.15 0.21 0.07 0 0.6 0.93 0.13 0 0.1 0.4 0.07 0.06 0.15 0.37 0.04 0.14 0.27 0.69 0.2 0.26 0.34 0.74 0.14 0.14 0.33 0.35 0.04 0.03 0.07 0.1 0.02 0 0.01 0.03 0.01

% ROUTINES POST m µ M σ 0.34 0.36 0.45 0.04 0.14 0.24 0.26 0.03 0 0.15 0.16 0.01 0 0.51 1 0.19 0.16 0.23 0.32 0.05 0 0.58 0.6 0.06 0 0.58 0.67 0.11 0 0.23 0.33 0.06 0.08 0.32 0.38 0.04 0 0 0.01 0 0 0.18 0.22 0.03 0.1 0.13 0.21 0.03 0 0.01 0.02 0.01 0 0.62 0.81 0.08 0 0.01 0.07 0.02 0.02 0.1 0.35 0.05 0.06 0.12 0.2 0.03 0.13 0.18 0.31 0.04 0.21 0.28 0.33 0.02 0.04 0.52 0.54 0.23 0 0.02 0.04 0.01

29

30

Project AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny Labs Quickgraph Rxx shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra

lang Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel C# C# C# C# C# C# C# Java Java Java Java Java Java

rev 306 1342 208 671 282 120 215 922 766 100 326 49 380 148 59 376 879 395 29 30 153

age 195 1006 114 747 716 524 716 285 108 171 106 30 100 68 7 119 366 389 106 350 169

m 17154 13154 0 0 3995 0 188 0 1831 6352 847 10296 22421 32 37 1113 15070 22813 4965 9362 2136

σ 19291 11922 8546 9175 4525 1753 1816 48763 23486 2834 4709 1002 4767 15998 887 3645 17731 2634 254 531 3723

# CLASSES m µ M σ 98 220 254 66 93 184 256 36 0 179 221 30 0 72 157 38 42 75 109 17 0 22 47 10 3 25 43 10 0 176 859 252 9 606 647 181 45 60 108 15 11 148 184 25 47 58 75 8 228 260 336 27 0 145 189 53 0 28 36 13 13 55 82 17 66 161 308 80 107 124 641 29 20 22 23 1 48 142 144 42 23 41 77 16

% CLASSES INV m µ M σ 0.48 0.54 0.63 0.05 0.49 0.66 0.69 0.04 0 0.07 0.08 0.01 0 0.12 0.29 0.04 0.5 0.81 0.87 0.11 0 0.18 0.38 0.1 0 0.52 0.57 0.09 0 0.63 0.8 0.13 0.24 0.34 0.58 0.06 0.01 0.04 0.06 0.01 0.04 0.47 0.52 0.06 0.35 0.38 0.42 0.02 0 0.02 0.04 0.01 0 0.42 0.44 0.08 0 0 0 0 0 0 0.03 0 0.11 0.17 0.26 0.05 0.12 0.47 0.62 0.04 0.04 0.09 0.09 0.01 0.08 0.1 0.11 0.01 0 0.06 0.1 0.03 m 524 1377 0 0 245 0 1 0 80 163 25 684 1075 0 0 274 304 815 154 798 335

# ROUTINES µ M 2395 2946 5214 7542 5300 8360 271 1304 1421 2900 346 630 118 221 2326 113813 7032 7894 214 309 886 1515 790 941 1263 1863 1448 2686 67 100 680 1199 746 3819 980 1761 171 173 952 959 612 1466 σ 1005 1326 2064 308 696 87 62 35183 2249 52 309 51 179 777 39 200 1130 176 6 66 355

Table 8. Project specification statistics for flattened classes.

LOC µ M 52958 65625 45200 61922 27498 40750 8457 53316 13069 21941 4131 10840 3591 6131 24146 163552 83444 88284 8358 20602 21700 29700 12141 14540 30343 40820 41616 55932 1741 2352 9550 13294 42055 73760 24993 35013 5751 5963 10688 10872 7549 15538

% ROUTINES SPEC m µ M σ 0.58 0.6 0.77 0.06 0.54 0.68 0.69 0.03 0 0.2 0.25 0.03 0 0.84 1 0.15 0.7 0.83 0.91 0.04 0 0.85 0.88 0.08 0 0.91 0.99 0.12 0 0.67 0.77 0.09 0.63 0.65 0.8 0.05 0 0.03 0.05 0.01 0.16 0.62 0.72 0.09 0.31 0.49 0.53 0.06 0 0.16 0.22 0.07 0 0.77 0.98 0.1 0 0.09 0.4 0.07 0.02 0.11 0.18 0.02 0.17 0.42 0.76 0.21 0.37 0.45 0.74 0.12 0.32 0.49 0.54 0.04 0.04 0.69 0.7 0.31 0 0.03 0.06 0.02

% ROUTINES PRE m µ M σ 0.37 0.39 0.48 0.04 0.38 0.48 0.49 0.02 0 0.11 0.18 0.03 0 0.49 0.6 0.16 0.51 0.57 0.74 0.05 0 0.46 0.53 0.05 0 0.5 0.83 0.09 0 0.49 0.67 0.08 0.5 0.5 0.74 0.06 0 0.03 0.04 0.01 0.16 0.46 0.53 0.06 0.19 0.37 0.43 0.06 0 0.15 0.21 0.07 0 0.69 0.95 0.11 0 0.08 0.4 0.07 0.02 0.11 0.18 0.02 0.13 0.25 0.68 0.2 0.3 0.38 0.67 0.11 0.14 0.33 0.35 0.04 0.02 0.04 0.05 0.01 0 0.02 0.05 0.02

% ROUTINES POST m µ M σ 0.38 0.41 0.59 0.06 0.3 0.45 0.49 0.03 0 0.1 0.13 0.02 0 0.62 1 0.18 0.53 0.61 0.76 0.06 0 0.69 0.73 0.07 0 0.68 0.72 0.12 0 0.4 0.52 0.11 0.08 0.43 0.48 0.06 0 0 0.01 0 0 0.27 0.35 0.06 0.12 0.16 0.19 0.02 0 0.01 0.02 0.01 0 0.72 0.86 0.08 0 0.01 0.07 0.01 0.01 0.08 0.18 0.03 0.08 0.14 0.35 0.04 0.18 0.22 0.31 0.03 0.21 0.28 0.33 0.02 0.04 0.67 0.67 0.3 0 0.01 0.02 0.01

−A inv weak vs same

−A inv strong vs same

2.90E+01 1.44E-02 -2.00E+00 -4.19E-01 2.90E+01 1.44E-02 -2.00E+00 -4.19E-01

+A inv strong vs same

post weak vs strong

1.90E+01 3.78E-02 0.00E+00 -4.75E-01 1.90E+01 3.78E-02 0.00E+00 -4.75E-01

+A inv weak vs same

NE pre weak vs strong

3.15E+01 1.95E-02 -2.00E+00 -4.04E-01 3.15E+01 1.95E-02 -2.00E+00 -4.04E-01

NE inv weak vs strong

pre weak vs strong

2.90E+01 4.78E-03 -1.10E+01 -5.03E-01 2.90E+01 4.78E-03 -1.10E+01 -5.03E-01

inv weak vs strong

NE chang vs unch spec

0.00E+00 9.54E-07 -6.80E+01 -9.96E-01 0.00E+00 9.54E-07 -6.80E+01 -9.96E-01

NE post weak vs strong

chang vs unch spec V p ∆(µ) d V p ∆(µ) d

0.00E+00 6.15E+01 1.82E-01 0.00E+00 -1.00E+00 0.00E+00 -1.82E-01 0.00E+00 6.15E+01 1.82E-01 0.00E+00 -1.00E+00 0.00E+00 -1.82E-01

5.85E+01 6.40E-01 0.00E+00 -1.29E-01 5.85E+01 6.40E-01 0.00E+00 -1.29E-01

0.00E+00 1.41E-02 0.00E+00 -6.27E-01 0.00E+00 1.41E-02 0.00E+00 -6.27E-01

0.00E+00 1.40E-02 0.00E+00 -4.17E-01 0.00E+00 1.40E-02 0.00E+00 -4.17E-01

3.00E+00 1.41E-01 0.00E+00 -3.09E-01 3.00E+00 1.41E-01 0.00E+00 -3.09E-01

0.00E+00 2.23E-02 0.00E+00 -5.25E-01 0.00E+00 2.23E-02 0.00E+00 -5.25E-01

−A inv weak vs same

−A inv strong vs same

5.00E+01 4.15E-02 -4.00E+00 -3.20E-01 5.00E+01 4.15E-02 -4.00E+00 -3.20E-01

+A inv strong vs same

2.55E+01 9.60E-02 0.00E+00 -5.85E-01 2.55E+01 9.60E-02 0.00E+00 -5.85E-01

+A inv weak vs same

post weak vs strong

5.45E+01 1.07E-01 -4.00E+00 -2.83E-01 5.45E+01 1.07E-01 -4.00E+00 -2.83E-01

NE inv weak vs strong

NE pre weak vs strong

7.75E+01 1.92E-01 -8.00E+00 -2.61E-01 7.75E+01 1.92E-01 -8.00E+00 -2.61E-01

inv weak vs strong

pre weak vs strong

0.00E+00 9.54E-07 -2.28E+02 -8.68E-01 0.00E+00 9.54E-07 -2.28E+02 -8.68E-01

NE post weak vs strong

NE chang vs unch spec

V p ∆(µ) d V p ∆(µ) d

chang vs unch spec

Table 9. Change analysis with majority for non-flattened (top) and flattened (bottom) classes.

0.00E+00 4.35E+01 7.00E-02 0.00E+00 -1.00E+00 0.00E+00 -3.32E-01 0.00E+00 4.35E+01 7.00E-02 0.00E+00 -1.00E+00 0.00E+00 -3.32E-01

4.80E+01 5.12E-01 0.00E+00 -1.21E-01 4.80E+01 5.12E-01 0.00E+00 -1.21E-01

0.00E+00 1.43E-02 0.00E+00 -5.91E-01 0.00E+00 1.43E-02 0.00E+00 -5.91E-01

0.00E+00 1.41E-02 0.00E+00 -4.11E-01 0.00E+00 1.41E-02 0.00E+00 -4.11E-01

3.50E+00 9.04E-02 0.00E+00 -3.34E-01 3.50E+00 9.04E-02 0.00E+00 -3.34E-01

0.00E+00 2.23E-02 0.00E+00 -5.37E-01 0.00E+00 2.23E-02 0.00E+00 -5.37E-01

Table 10. Change analysis for non-flattened (top) and flattened (bottom) classes.

31

32

Project AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny Labs Quickgraph Rxx shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra Overall

τ 0.98 0.27 0.66 0.86 0.13 0.81 -0.10 0.77 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 1.00 0.64

0.00E+00 0.00E+00 0.00E+00 4.36E-09 6.15E-11 0.00E+00 0.00E+00

p 0.00E+00 0.00E+00 4.75E-12 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 3.65E-08 0.00E+00 0.00E+00 0.00E+00 0.00E+00 4.20E-11 0.00E+00 0.00E+00 0.00E+00 0.00E+00 9.32E-12 2.07E-08 0.00E+00 0.00E+00

τ 0.60 0.62 0.34 0.89 0.38 0.58 0.80 0.78 -0.14 0.97 0.45 0.97 1.00 0.38 1.00 0.96 0.98 0.89 1.00 0.79 1.00 0.82 0.00E+00 0.00E+00 3.22E-12 2.12E-09 0.00E+00 0.00E+00

p 0.00E+00 0.00E+00 1.24E-10 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 2.62E-14 0.33 0.66 1.00 0.98 1.00 0.75

τ 0.75 0.38 0.31 0.36 0.70 0.89 1.00 0.76 0.29 1.00 0.78 0.94 1.00 0.92 1.00

0.00E+00 1.80E-02 0.00E+00 1.21E-07 9.76E-09 0.00E+00 0.00E+00

p 1.55E-04 0.00E+00 0.00E+00 0.00E+00 0.00E+00 1.41E-06 0.00E+00 0.00E+00 0.00E+00 0.00E+00 4.52E-06 4.19E-02 0.00E+00 0.00E+00

1.00 -0.06 0.91 1.00 1.00 0.80 0.40

τ 0.16 0.46 0.95 0.97 0.45 0.36 0.90 0.79 0.71 1.00 -0.18 -0.22 1.00 1.00

CLASSES W / INV AVG PRE STRENGTH AVG POST STRENGTH AVG INV STRENGTH

p 0.00E+00 0.00E+00 0.00E+00 0.00E+00 1.44E-03 0.00E+00 4.19E-02 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00

%

Table 11. Correlation of measures in flat and non-flat classes.

τ 0.65 0.17 -0.01 0.60 0.01 -0.05 0.92 0.28 0.91 0.98 0.90 0.64 0.99 0.54 0.99 0.56 0.89 0.97 1.00 0.97 0.79 0.53

ROUTINES W / SPEC

p 0.00E+00 0.00E+00 8.98E-01 0.00E+00 8.88E-01 4.28E-01 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 9.79E-10 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 5.70E-12 3.43E-12 0.00E+00 0.00E+00

%

Project AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny Labs Quickgraph Rxx shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra Overall

% SPEC /# ROUTINES p τ 1.02E-94 -0.82 0.00E+00 0.66 1.17E-10 0.31 9.98E-04 -0.09 3.04E-05 0.17 2.16E-04 -0.24 1.94E-32 -0.56 5.77E-74 -0.40 0.00E+00 -0.95 0.00E+00 0.67 4.77E-100 -0.81 4.64E-01 -0.08 1.89E-06 0.17 4.76E-41 -0.76 1.44E-03 0.32 7.14E-62 -0.59 0.00E+00 0.54 0.00E+00 0.47 5.01E-01 0.10 7.35E-06 0.63 1.04E-02 0.15 1.15E-05 0.03

# SPEC /# ROUTINES p τ 0.00E+00 0.93 0.00E+00 0.98 0.00E+00 0.98 0.00E+00 0.97 0.00E+00 0.53 0.00E+00 0.91 0.00E+00 0.99 0.00E+00 0.97 0.00E+00 0.56 0.00E+00 0.76 0.00E+00 0.97 6.07E-06 0.48 0.00E+00 0.48 0.00E+00 0.97 4.44E-16 0.84 0.00E+00 0.82 0.00E+00 0.93 0.00E+00 0.81 3.87E-02 0.32 4.36E-09 0.84 0.00E+00 0.64 0.00E+00 0.76

% INV /# CLASSES p τ 1.21E-117 -0.93 1.13E-08 0.11 8.25E-04 -0.17 0.00E+00 0.35 5.69E-07 -0.21 6.16E-13 0.51 0.00E+00 0.60 0.00E+00 0.57 8.94E-209 -0.77 9.32E-01 0.01 1.94E-88 -0.77 5.23E-08 0.58 0.00E+00 0.63 4.32E-03 0.17

# INV /# CLASSES p τ 0.00E+00 0.76 0.00E+00 0.95 0.00E+00 0.85 0.00E+00 0.92 0.00E+00 0.70 0.00E+00 0.91 0.00E+00 0.95 0.00E+00 0.94 0.00E+00 0.28 2.90E-12 0.58 0.00E+00 0.65 8.88E-16 0.88 0.00E+00 0.83 0.00E+00 0.96

2.32E-01 3.55E-279 2.10E-95 6.06E-02 4.43E-01 9.82E-11 0.00E+00

2.32E-01 0.00E+00 1.66E-07 5.77E-03 6.61E-05 0.00E+00 0.00E+00

-0.05 -0.83 -0.76 -0.33 -0.12 0.38 0.20

-0.05 0.88 0.20 0.51 0.64 0.85 0.61

Table 12. Correlation of measures of specification in non-flat classes.

33

AVG /% PRE

p 0.00E+00 0.00E+00 1.69E-01 2.71E-05 4.23E-04 1.55E-05 0.00E+00 3.65E-03 6.75E-32 2.88E-10 0.00E+00 7.32E-14 6.66E-02 1.67E-11 0.00E+00 5.85E-01 2.76E-212 3.93E-63 5.90E-03 2.76E-10 0.00E+00 0.00E+00

τ 0.65 0.44 0.07 -0.11 0.15 0.30 0.54 0.07 -0.30 0.48 0.32 -0.81 0.07 -0.38 0.87 -0.02 -0.72 -0.59 -0.40 -0.88 0.75 0.32

AVG /% POST

p 0.00E+00 0.00E+00 4.94E-01 1.42E-01 0.00E+00 7.87E-10 0.00E+00 0.00E+00 1.85E-05 0.00E+00 0.00E+00 1.46E-03 0.00E+00 1.86E-33 4.23E-11

τ 0.43 0.26 0.03 -0.04 0.52 0.41 0.58 0.51 0.12 0.91 0.53 0.34 0.79 -0.70 0.77

4.73E-07 3.50E-21 9.38E-01 3.59E-04 0.00E+00 1.23E-12

0.12 -0.34 0.01 -0.54 0.71 0.05

AVG /% INV

p 0.00E+00 0.00E+00 5.23E-01 6.90E-11 6.58E-01 6.79E-02 2.83E-13 0.00E+00 0.00E+00 4.31E-04 6.67E-13 1.15E-08 0.00E+00 5.77E-01

τ 0.78 0.19 -0.04 0.18 0.02 0.13 0.36 0.57 0.57 -0.29 0.29 0.62 0.54 0.03

0.00E+00 0.00E+00 0.00E+00 5.09E-01 1.68E-04 0.00E+00 0.00E+00

1.00 0.47 0.63 -0.12 -0.61 0.57 0.47

Project AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny Labs Quickgraph Rxx shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra Overall

% SPEC /# ROUTINES p τ 1.28E-70 -0.70 8.85E-06 -0.08 1.51E-14 0.37 0.00E+00 0.29 6.58E-01 0.02 2.41E-01 0.08 2.47E-34 -0.58 0.00E+00 0.20 8.05E-274 -0.87 0.00E+00 0.64 9.03E-93 -0.77 8.77E-06 -0.46 1.92E-06 0.17 3.92E-09 -0.33 2.08E-03 0.31 9.07E-36 -0.44 0.00E+00 0.64 0.00E+00 0.38 5.01E-01 0.10 9.35E-06 0.62 6.22E-10 0.36 9.70E-03 0.02

# SPEC /# ROUTINES p τ 0.00E+00 0.92 0.00E+00 0.92 0.00E+00 0.98 0.00E+00 0.99 0.00E+00 0.98 0.00E+00 0.98 0.00E+00 0.99 0.00E+00 0.98 0.00E+00 0.89 0.00E+00 0.75 0.00E+00 0.97 9.08E-03 0.28 0.00E+00 0.48 0.00E+00 0.97 4.44E-16 0.84 0.00E+00 0.78 0.00E+00 0.93 0.00E+00 0.80 3.87E-02 0.32 2.99E-09 0.85 0.00E+00 0.84 0.00E+00 0.80

% INV /# CLASSES p τ 3.09E-117 -0.93 9.35E-35 -0.23 8.13E-19 -0.44 0.00E+00 0.47 3.63E-13 0.30 2.22E-16 0.58 3.70E-04 -0.17 0.00E+00 0.69 8.94E-209 -0.77 9.32E-01 0.01 1.94E-88 -0.77 5.23E-08 0.58 0.00E+00 0.63 4.32E-03 0.17

# INV /# CLASSES p τ 0.00E+00 0.88 0.00E+00 0.94 0.00E+00 0.89 0.00E+00 0.92 0.00E+00 0.72 0.00E+00 0.88 0.00E+00 0.97 0.00E+00 0.95 0.00E+00 0.28 2.90E-12 0.58 0.00E+00 0.65 8.88E-16 0.88 0.00E+00 0.83 0.00E+00 0.96

2.32E-01 3.55E-279 2.10E-95 6.06E-02 4.43E-01 9.82E-11 0.00E+00

2.32E-01 0.00E+00 1.66E-07 5.77E-03 6.61E-05 0.00E+00 0.00E+00

-0.05 -0.83 -0.76 -0.33 -0.12 0.38 0.17

-0.05 0.88 0.20 0.51 0.64 0.85 0.59

Table 13. Correlation of measures of specification in flat classes.

34

AVG /% PRE

p 0.00E+00 0.00E+00 0.00E+00 7.60E-05 0.00E+00 4.86E-05 8.88E-16 4.88E-15 0.00E+00 3.48E-11 0.00E+00 1.48E-16 7.10E-02 3.79E-09 0.00E+00 2.22E-14 4.87E-196 7.29E-65 5.90E-03 1.14E-06 0.00E+00 0.00E+00

τ 0.51 0.33 0.50 -0.10 0.53 0.27 0.39 0.17 0.51 0.50 0.60 -0.89 0.06 -0.34 0.88 -0.31 -0.69 -0.59 -0.40 -0.68 0.75 0.20

AVG /% POST

p 0.00E+00 7.64E-24 4.93E-07 3.25E-64 8.23E-43 1.87E-02 2.66E-05 2.95E-10 4.31E-01 0.00E+00 0.00E+00 2.58E-03 0.00E+00 9.97E-11 4.15E-11

τ 0.38 -0.19 0.25 -0.45 -0.56 0.16 0.21 0.14 0.02 0.92 0.51 0.32 0.80 -0.37 0.78

0.00E+00 1.50E-08 9.38E-01 2.12E-03 0.00E+00 0.00E+00

0.22 -0.20 0.01 -0.47 0.72 0.25

AVG /% INV

p 1.42E-01 0.00E+00 6.44E-13 4.99E-11 5.37E-14 0.00E+00 1.36E-03 0.00E+00 0.00E+00 4.31E-04 4.52E-80 1.00E-06 0.00E+00 5.77E-01

τ -0.06 0.16 -0.39 0.18 0.31 0.80 0.16 0.69 0.42 -0.29 -0.73 -0.53 0.54 0.03

0.00E+00 3.26E-114 0.00E+00 5.09E-01 1.68E-04 3.13E-09 0.00E+00

1.00 -0.54 0.64 -0.12 -0.61 0.36 0.57

% Project AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny Labs Quickgraph Rxx shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra Overall

PRE PUBLIC / PRIVATE

p 0.00E+00 0.00E+00 2.16E-09 1.17E-05 9.01E-27 1.31E-03 1.59E-02 1.57E-07 0.00E+00 0.00E+00 0.00E+00 1.66E-09 1.98E-07 7.66E-05 6.28E-09 1.97E-02 0.00E+00 0.00E+00 2.01E-08 5.83E-02 0.00E+00 0.00E+00

τ 0.76 0.73 0.29 -0.12 -0.44 -0.22 0.12 -0.12 0.94 0.84 0.36 -0.63 0.19 0.23 0.59 -0.08 0.40 0.33 0.84 0.26 0.59 0.38

%

POST PUBLIC / PRIVATE

p 0.00E+00 0.00E+00 0.00E+00 8.31E-01 1.05E-36 2.35E-07 0.00E+00 2.08E-02 0.00E+00 0.00E+00 0.00E+00 4.42E-03 0.00E+00 5.46E-06 4.78E-05

τ 0.51 0.57 0.49 -0.01 -0.52 0.34 0.65 0.05 0.73 0.80 0.86 0.30 0.80 0.26 0.42

7.38E-12 1.56E-11 1.45E-01 2.22E-06 0.00E+00 0.00E+00

0.16 0.24 0.21 0.67 0.78 0.38

%

SPEC PUBLIC / PRIVATE

p 0.00E+00 0.00E+00 4.18E-01 1.48E-39 3.27E-30 7.48E-05 3.59E-02 2.66E-26 0.00E+00 0.00E+00 0.00E+00 2.20E-06 1.45E-07 2.95E-03 3.11E-04 1.86E-02 0.00E+00 0.00E+00 1.55E-08 7.73E-07 0.00E+00 0.00E+00

Table 14. Correlation of measures between public and private routines in non-flat classes.

35

τ 0.75 0.64 0.04 -0.36 -0.47 -0.26 0.10 -0.24 0.94 0.85 0.66 -0.50 0.19 0.17 0.37 -0.08 0.46 0.51 0.82 0.68 0.81 0.39

% Project AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny Labs Quickgraph Rxx shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra Overall

PRE PUBLIC / PRIVATE

p 0.00E+00 0.00E+00 1.00E-06 7.45E-02 3.17E-01 1.85E-03 1.39E-01 0.00E+00 0.00E+00 0.00E+00 0.00E+00 2.89E-11 4.07E-08 1.01E-04 9.05E-09 1.10E-44 0.00E+00 0.00E+00 2.01E-08 1.12E-01 0.00E+00 0.00E+00

τ 0.66 0.41 0.24 0.05 -0.04 -0.21 0.07 0.37 0.68 0.83 0.40 -0.69 0.20 0.22 0.59 -0.50 0.50 0.60 0.84 0.22 0.87 0.35

%

POST PUBLIC / PRIVATE

p 0.00E+00 5.13E-18 0.00E+00 1.07E-08 0.00E+00 3.49E-01 2.84E-04 2.68E-01 0.00E+00 0.00E+00 0.00E+00 2.37E-02 0.00E+00 0.00E+00 4.59E-05

τ 0.61 -0.16 0.60 -0.15 0.54 -0.06 0.18 0.02 0.27 0.80 0.80 0.23 0.81 0.47 0.43

5.61E-06 5.17E-04 1.45E-01 6.58E-07 0.00E+00 0.00E+00

0.11 0.12 0.21 0.70 0.77 0.50

%

SPEC PUBLIC / PRIVATE

p 0.00E+00 8.27E-01 2.25E-10 3.82E-07 8.73E-06 2.13E-06 1.19E-02 0.00E+00 0.00E+00 0.00E+00 0.00E+00 3.94E-12 4.19E-09 4.77E-04 7.61E-04 4.53E-43 0.00E+00 0.00E+00 3.78E-08 3.65E-07 0.00E+00 0.00E+00

Table 15. Correlation of measures between public and private routines in flat classes.

36

τ 0.76 0.00 0.31 -0.14 -0.18 0.32 0.12 0.19 0.84 0.83 0.66 -0.72 0.21 0.20 0.34 -0.49 0.55 0.59 0.80 0.70 0.90 0.42

Project AutoTest EiffelBase EiffelProgramAnalysis GoboKernel GoboStructure GoboTime GoboUtility GoboXML Boogie CCI Dafny Labs Quickgraph Rxx shweet DirectVCGen ESCJava JavaFE Logging RCC Umbra

% PRE VOID % PRE ∀, ∃ m µ M σ m µ M σ 0.67 0.69 0.76 0.02 0 0 0 0 0.23 0.36 0.46 0.05 0 0 0 0 0 0.62 0.67 0.08 0 0 0 0 0 0.56 1 0.19 0 0 0.01 0 0.35 0.43 0.75 0.12 0 0 0 0 0 0.65 0.8 0.08 0 0 0 0 0 0.93 1 0.12 0 0 0 0 0 0.64 0.75 0.05 0 0 0 0 0.94 0.96 0.99 0.01 0 0.01 0.01 0 0 0.8 0.92 0.32 0 0 0 0 0.8 0.96 0.98 0.02 0 0 0 0 0.93 0.96 0.97 0.01 0 0 0 0 0 0.94 0.99 0.34 0 0.01 0.07 0.02 0 0.95 1 0.08 0 0 0 0 0 0.83 1 0.4 0 0 0 0 1 1 1 0 0 0 0 0 0.85 0.93 0.99 0.05 0 0 0 0 0.92 0.94 0.98 0.02 0 0 0.01 0 0.88 0.95 0.95 0.02 0 0 0 0 0.71 0.88 0.9 0.08 0 0 0 0 0 0.25 0.33 0.16 0 0 0 0

% POST VOID % POST ∀, ∃ m µ M σ m µ M σ 0.35 0.38 0.64 0.12 0 0.01 0.02 0.01 0.06 0.14 0.25 0.06 0 0 0 0 0 0.19 0.22 0.02 0 0 0 0 0 0.47 1 0.16 0 0 0 0 0.03 0.07 0.1 0.02 0 0 0 0 0 0.29 0.53 0.11 0 0 0 0 0 0.62 0.89 0.15 0 0 0 0 0 0.37 0.61 0.06 0 0 0 0 0.72 0.9 1 0.04 0 0 0.01 0 0 0 1 0.49 0 0 0 0 0 0.88 0.94 0.12 0 0 0 0 0.65 0.71 0.8 0.05 0 0 0 0 0 0.34 0.67 0.21 0 0 0 0 0 0.92 1 0.09 0 0 0 0 0 1 1 0.49 0 0 0 0 1 1 1 0 0 0 0 0 0.45 0.69 0.88 0.11 0 0.01 0.03 0.01 0.65 0.69 0.84 0.05 0 0 0 0 0 0.28 0.43 0.1 0 0 0 0 0.16 0.89 0.94 0.36 0 0 0 0 0 0 0 0 0 0 0 0

% POST OLD m µ M σ 0 0.02 0.02 0.01 0.01 0.13 0.2 0.02 0 0.02 0.02 0.01 0 0.05 0.2 0.04 0.07 0.39 0.52 0.13 0 0.29 0.32 0.06 0 0 0.02 0.01 0 0.01 0.03 0.01 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.1 0.03 0 0 1 0.31 0 0 0.01 0.01 0 0 0 0 0 0 0 0 0 0 0.02 0 0.02 0.03 0.04 0.01 0.02 0.02 0.03 0 0 0 0 0 0 0.67 0.67 0.32

% INV VOID % INV ∀, ∃ m µ M σ m µ M σ 0.85 0.86 0.98 0.04 0.02 0.02 0.02 0 0.08 0.24 0.29 0.06 0 0 0 0 0 0.14 0.22 0.08 0 0 0 0 0 0.73 1 0.21 0 0 0 0 0.33 0.68 0.78 0.13 0 0 0 0 0 0.5 0.6 0.17 0 0 0 0 0 0.82 1 0.14 0 0 0 0 0 0.85 0.94 0.04 0 0 0 0 1 1 1 0 0 0.06 0.07 0.02 1 1 1 0 0 0 0 0 0.98 1 1 0 0 0.01 0.02 0 0.92 0.97 1 0.03 0 0 0 0 0 0.2 0.36 0.11 0 0.1 0.17 0.06 0 1 1 0.12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.37 0.54 0.63 0.09 0 0.04 0.09 0.04 0.6 0.77 0.83 0.04 0.08 0.09 0.19 0.02 0 0 0 0 0 0 0 0 0.5 0.5 1 0.22 0 0 0 0 0 0 0 0 0 0.25 0.25 0.12

Table 16. Syntactic elements found in contracts (non-flattened classes).

37

11

Non-flat classes

The following pages show the plots for the 21 projects of our study, considering nonflat classes. The dotted lines, when present, mark mean values of the various quantities. The thin continuous lines that do not appear in the legend track the total number of routines, classes, or both, whose absolute values are scaled to the range determined by the main data represented in the graph. When two of such thin lines are present, the red one tracks the number of classes and the aquamarine one tracks the number of routines. When only one (red) thin line is present, it tracks the number of routines or classes according to the main content of the graph.

38

# routines

# routines

12

10

8

6

4

2

spec

body+spec 0 (nonempty 50 spec)100 body

revision

150

200

250

300

AutoTest: # changed routines (for nonempty spec)

150

revision

200

250

80

800

revision

600

1000

1200

spec

body+spec 0 (nonempty 20 spec) 40 body revision

60

80

100

120

GoboTime: # changed routines (for nonempty spec)

spec

body+spec 200 spec) 400 body0 (nonempty

EiffelBase: # changed routines (for nonempty spec)

revision

100

150

200

body+spec 0 (nonempty 50 body spec) spec

100

150

200

GoboUtility: # changed routines (for nonempty spec)

body+spec 0 (nonempty spec) 50 body spec

EiffelProgramAnalysis: # changed routines (for nonempty spec)

Fig. 17. Non flat: Changed routines (with nonempty unchanged spec) (Eiffel projects)

spec

body+spec 0 (nonempty 50 spec) 100 body

GoboStructure: # changed routines (for nonempty spec)

0

15

10

5

0

# routines # routines

60 40 20 0 8 6 4 2 0

6 5 4 3 2 1 0 10 8 6

revision

2

# routines # routines

8

0

4

# routines # routines

6 4 2 0 25 20 15 10 5 0

39

400 revision

300

500

600

body+spec body0 (nonempty200 spec) spec

revision

400

600

800

GoboXML: # changed routines (for nonempty spec)

spec

body+spec 0 (nonempty 100 spec) 200 body

GoboKernel: # changed routines (for nonempty spec)

# routines

150

100

50

0

120

100

80

400

revision

600

800

body+spec 0 (nonempty spec) 100 body spec

200

300

Quickgraph: # changed routines (for nonempty spec)

spec

body+spec 200 body (nonempty spec)

Boogie: # changed routines (for nonempty spec)

40 revision

60

80

body+spec 0 (nonempty spec) 50 body spec revision

100

150

100

Rxx: # changed routines (for nonempty spec)

body+spec 0 (nonempty 20spec) body spec

CCI: # changed routines (for nonempty spec)

Fig. 18. Non flat: Changed routines (with nonempty unchanged spec) (C# projects)

revision

40

20

# routines

2.0 1.5

14 12 10 8 6 4

1.0 0.5 0.0 150 100

0

60

# routines # routines 50 0

# routines # routines

250

revision

200

300

350

400

spec

body+spec 0 (nonempty 10 spec) 20 body

revision

30

40

50

60

shweet: # changed routines (for nonempty spec)

spec

body+spec 100 150 body (nonempty spec)

Dafny: # changed routines (for nonempty spec) 35 30 25 20 15 10 5 0

2 0 2.0 1.5 1.0 0.5 0.0

40

# routines

spec

body+spec 0 (nonempty 10 spec) body

20 revision

30

40

50

Labs: # changed routines (for nonempty spec)

# routines

# routines

revision

200

300

400

15

revision

20

25

30

body+spec 0 (nonempty 5 body spec)10 spec

revision

400

600

800

revision

15

20

25

30

RCC: # changed routines (for nonempty spec)

body+spec 0 (nonempty200 body spec) spec

ESCJava: # changed routines (for nonempty spec)

Fig. 19. Non flat: Changed routines (with nonempty unchanged spec) (Java projects)

spec

body+spec 0 (nonempty 5 spec)10 body

Logging: # changed routines (for nonempty spec)

body+spec 0 (nonempty 100 body spec) spec

DirectVCGen: # changed routines (for nonempty spec) 300 250 200

300 250 200 150

25

20

15

10

5

0

30

25

20

15

10

5

0

# routines # routines

100 50 0 200 150 100 50 0

# routines # routines

150 100 50 0 1.0 0.8 0.6 0.4 0.2 0.0

41

200 revision

300

400

body+spec 0 (nonempty spec)50 body spec

revision

100

150

Umbra: # changed routines (for nonempty spec)

body+spec 0 (nonempty spec) 100 body spec

JavaFE: # changed routines (for nonempty spec)

# routines

6

5

4

3

2

1

100

150

revision

200

250

300

0 body+spec spec

50

100

revision

150

200

250

GoboStructure: # changed routines (w/ or w/o body change)

0 50 body+spec spec

AutoTest: # changed routines (w/ or w/o body change) 80

400

800

revision

600

1000

1200

0 20 body+spec spec

40 revision

60

80

100

120

GoboTime: # changed routines (w/ or w/o body change)

0 200 body+spec spec

EiffelBase: # changed routines (w/ or w/o body change)

50

100 revision

150

200

0 body+spec spec

50

100

150

200

GoboUtility: # changed routines (w/ or w/o body change)

0 body+spec spec

revision

200

400 revision

300

500

600

0 body+spec spec

200

revision

400

600

800

GoboXML: # changed routines (w/ or w/o body change)

0 100 body+spec spec

EiffelProgramAnalysis: # changed routines (w/ or w/o body change) GoboKernel: # changed routines (w/ or w/o body change)

Fig. 20. Non-flat: Routines with changed specification (with or without body changing) (Eiffel projects)

# routines

0

15

10

5

0

# routines # routines

60 40 20 0 4 3 2 1 0

6 5 4 3 2 1 0 10 8 6 2

# routines # routines

8

0

4

# routines # routines

6 4 2 0 25 20 15 10 5 0

42

# routines

150

100

50

200 body+spec spec

400

revision

600

800

Boogie: # changed routines (w/ or w/o body change)

0 body+spec spec

100

200

300

Quickgraph: # changed routines (w/ or w/o body change)

0

120

100

80

60

20

40 revision

60

80

100

0 body+spec spec

50 revision

100

150

Rxx: # changed routines (w/ or w/o body change)

0 body+spec spec

CCI: # changed routines (w/ or w/o body change)

150

250

revision

200

300

350

400

0 10 body+spec spec

20

revision

30

40

50

60

shweet: # changed routines (w/ or w/o body change)

100 body+spec spec

Dafny: # changed routines (w/ or w/o body change)

Fig. 21. Non-flat: Routines with changed specification (with or without body changing) (C# projects)

revision

20

# routines

2.0 1.5

0

40

# routines # routines

14 12 10 8 6 4

1.0 0.5 0.0 14 12 10 8 6 4 2 0

# routines # routines

35 30 25 20 15 10 5 0

2 0 2.0 1.5 1.0 0.5 0.0

43

# routines

0 body+spec spec

10

20 revision

30

40

50

Labs: # changed routines (w/ or w/o body change)

# routines

100

200

revision

300

400

0 5 body+spec spec

10

revision

15

20

25

30

Logging: # changed routines (w/ or w/o body change)

0 body+spec spec

DirectVCGen: # changed routines (w/ or w/o body change)

8

6

4

2

0

300 250 200

200 revision

400

600

800

0 5 body+spec spec

10 revision

15

20

25

30

RCC: # changed routines (w/ or w/o body change)

0 body+spec spec

ESCJava: # changed routines (w/ or w/o body change) 300 250 200

100

200 revision

300

400

0 body+spec spec

50 revision

100

150

Umbra: # changed routines (w/ or w/o body change)

0 body+spec spec

JavaFE: # changed routines (w/ or w/o body change)

Fig. 22. Non-flat: Routines with changed specification (with or without body changing) (Java projects)

# routines

30

25

20

15

10

5

0

# routines # routines

150 100 50 0 200 150 100 50 0

# routines # routines

150 100 50 0 1.0 0.8 0.6 0.4 0.2 0.0

44

# routines

# routines

revision

150

200

250

300

spec

revision

150

200

250

800

revision

600

1000

1200

spec

body+spec body 0 (nonempty 20 spec) 40 body revision

60

80

100

120

GoboTime: # changed routines (types of change)

spec

body+spec body 200 spec) 400 body0 (nonempty

EiffelBase: # changed routines (types of change)

Fig. 23. Non-flat: changed routines (types of change) (Eiffel projects)

body+spec body 0 (nonempty 50 spec) 100 body

GoboStructure: # changed routines (types of change)

spec

body+spec body 0 (nonempty 50 spec)100 body

AutoTest: # changed routines (types of change) 250 200

35

30

25

20

15

10

5

0

50

40

30

20

10

0

# routines # routines

150 100 50 0 15 10 5 0

# routines # routines

revision

100

150

200

body+spec body 0 (nonempty 50 body spec) spec

revision

100

150

200

GoboUtility: # changed routines (types of change)

body+spec body 0 (nonempty spec) 50 body spec

EiffelProgramAnalysis: # changed routines (types of change) 15 10 5 0 10 8 6 4 2 0

# routines # routines

40 30 20 10 0 120 100 80 60 40 20 0

45

400 revision

300

500

600

body+spec body body0 (nonempty200 spec) spec

revision

400

600

800

GoboXML: # changed routines (types of change)

spec

body+spec body 0 (nonempty 100 spec) 200 body

GoboKernel: # changed routines (types of change)

150

100

50

0

120

100

80

# routines

# routines

400

revision

600

800

revision

200

300

40 revision

60

80

body+spec body 0 (nonempty spec) 50 body spec revision

100

Rxx: # changed routines (types of change)

body+spec body 0 (nonempty 20spec) body spec

CCI: # changed routines (types of change)

Fig. 24. Non-flat: changed routines (types of change) (C# projects)

body+spec body 0 (nonempty spec) 100 body spec

Quickgraph: # changed routines (types of change)

spec

body+spec body 200 body (nonempty spec)

Boogie: # changed routines (types of change) 10 8 6 4 2 0 150 100

150

100

50

# routines # routines

20 15 10 spec

250

revision

200

300

350

revision

30

40

50

shweet: # changed routines (types of change)

body+spec body 0 (nonempty 10 spec) 20 body

spec

body+spec body 100 150 body (nonempty spec)

Dafny: # changed routines (types of change)

60

400

50 40 30 20 10 0

5 0 15 10

0

60

40

20

0

# routines # routines 5 0

46

# routines

spec

body+spec body 0 (nonempty 10 spec) body

20 revision

30

40

Labs: # changed routines (types of change)

50

# routines

# routines

revision

200

300

spec

revision

15

20

25

30

400

body+spec body 0 (nonempty 5 body spec)10 spec

revision

400

600

800

revision

15

20

25

RCC: # changed routines (types of change)

body+spec body 0 (nonempty200 body spec) spec

30

ESCJava: # changed routines (types of change)

Fig. 25. Non-flat: changed routines (types of change) (Java projects)

body+spec body 0 (nonempty 5 spec)10 body

Logging: # changed routines (types of change)

body+spec body 0 (nonempty 100 body spec) spec

DirectVCGen: # changed routines (types of change) 300 250 200

300 250 200

80

60

40

20

0

30

25

20

15

10

5

0

# routines # routines

150 100 50 0 200 150 100 50 0

# routines # routines

150 100 50 0 25 20 15 10 5 0

47

200 revision

300

body+spec body 0 (nonempty spec)50 body spec

revision

100

400

150

Umbra: # changed routines (types of change)

body+spec body 0 (nonempty spec) 100 body spec

JavaFE: # changed routines (types of change)

3.5

3.0

2.5

2.0

1.5

1.0

0.5

0.0

3.5

3.0

2.5

2.0

1.5

100

revision

150

200

250

% inv mean inv # inv0 weak 50 # inv strong

100

150

200

250

GoboStructure: Average and % inv

% inv mean inv # inv0 weak 50 # inv strong

AutoTest: Average and % inv

300

400

800

revision

600

1000

40 revision

60

80

1200

100

GoboTime: Average and % inv

% inv mean inv 0 weak 20 # inv # inv strong

% inv mean inv # inv0 weak 200 # inv strong

EiffelBase: Average and % inv

120

% inv mean inv 0 weak # inv # inv strong

revision

100

150

50

100

150

GoboUtility: Average and % inv

50

200

200

EiffelProgramAnalysis: Average and % inv

% inv mean inv 0 weak # inv # inv strong

Fig. 26. Non-flat: Average invariant strength and % of classes with invariant (Eiffel projects)

revision

0.5

0.0

1.0

12 10 8 6 4 2 0 3.0 2.5 2.0 1.5 1.0 0.5 0.0

1.2 1.0 0.8 0.6 0.4 0.2 0.0 6 5 4 3

revision

1 0

2

2.0 1.5 1.0 0.5 0.0 12 10 8 6 4 2 0

48

% inv mean inv # inv0 weak # inv strong

% inv mean inv # inv0 weak 100 # inv strong

400 revision

300

500

200

revision

400

600

GoboXML: Average and % inv

200

600

800

GoboKernel: Average and % inv

35

30

25

20

15

10

5

0

5

4

3

2

1

% inv mean inv # inv0 weak # inv strong

# inv strong

% inv mean inv 200 # inv weak

revision

600

100

revision

200

300

Quickgraph: Average and % inv

400

Boogie: Average and % inv

800

% inv mean inv 0 weak # inv # inv strong

% inv mean inv 0 weak # inv # inv strong 20 revision

60

50 revision

100

Rxx: Average and % inv

40

CCI: Average and % inv

80

150

100

% inv mean inv 0 weak 10 # inv # inv strong

# inv strong

% inv mean inv 100 # inv weak

Fig. 27. Non-flat: Average invariant strength and % of classes with invariant (C# projects)

0

2.0 1.5 1.0 0.5 0.0 8 6 4 2 0

8 6

250

revision

200

300

20

revision

30

40

shweet: Average and % inv

150

Dafny: Average and % inv

50

350

60

400

8 6 4 2 0

4 2 0 1.0 0.5 0.0 −0.5 −1.0

49

% inv mean inv 0 weak # inv # inv strong

10

20 revision

30

Labs: Average and % inv

40

50

2.0

1.5

1.0

0.5

0.0

2.0

1.5

1.0

0.5

% inv mean inv # 0inv weak 5 # inv strong

% inv mean inv #0 inv weak # inv strong

revision

200

300

10

revision

15

20

Logging: Average and % inv

100

25

DirectVCGen: Average and % inv

30

400

% inv mean inv #0 inv weak 5 # inv strong

% inv mean inv 0 weak # inv # inv strong revision

400

600

10 revision

15

20

RCC: Average and % inv

200

ESCJava: Average and % inv

25

800

30

% inv mean inv 0 weak # inv # inv strong

% inv mean inv # inv0 weak # inv strong

Fig. 28. Non-flat: Average invariant strength and % of classes with invariant (Java projects)

0.0

3.5 3.0 2.5 2.0 1.5 1.0 0.5 0.0 6 5 4 3 2 1 0

5 4 3 2 1 0 2.0 1.5 1.0 0.5 0.0

50

200 revision

300

50 revision

100

Umbra: Average and % inv

100

JavaFE: Average and % inv

150

400

100

revision

150

200

250

50

100

revision

150

200

250

GoboStructure: # classes and invariants

50

300

250 200 # inv

classes 0 w/ inv

# inv

classes 0 w/ inv 400

800

revision

600

1000

1200

20

40 revision

60

80

100

GoboTime: # classes and invariants

200

EiffelBase: # classes and invariants

120

Fig. 29. Non-flat: # of classes, classes with invariants, invariant clauses (Eiffel projects)

# inv

classes 0 w/ inv

# inv

classes 0 w/ inv

AutoTest: # classes and invariants 200 150

300

250

200

150

100

50

# classes or invariants

# classes or invariants

100

80

60

40

20

# classes or invariants # classes or invariants

150 100 50 40 30 20 10 0

# classes or invariants # classes or invariants

100 50 0 40 30 20 10 0 # inv

classes 0 w/ inv

# inv

classes 0 w/ inv revision

100

150

50

revision

100

150

GoboUtility: # classes and invariants

50

200

200

EiffelProgramAnalysis: # classes and invariants

# classes or invariants # classes or invariants

150 100 50 0 800 600 400 200 0

51

# inv

classes 0 w/ inv

# inv

classes 0 w/ inv

200

400 revision

300

500

600

200

revision

400

600

800

GoboXML: # classes and invariants

100

GoboKernel: # classes and invariants

revision

600

800

100

200

revision

300 # inv

classes 0 w/ inv

# inv

classes 0 w/ inv 40 revision

60

80

50 revision

100

Rxx: # classes and invariants

20

CCI: # classes and invariants

150

100

Fig. 30. Non-flat: # of classes, classes with invariants, invariant clauses (C# projects)

# inv

classes 0 w/ inv

400

Quickgraph: # classes and invariants

classes 200 w/ inv # inv

Boogie: # classes and invariants 100 80 60

600

500

400

300

200

100

0

# classes or invariants

# classes or invariants

300

250

200

150

100

50

0

# classes or invariants # classes or invariants

40 20 0 250 200 150 100 50 0

# classes or invariants # classes or invariants

classes w/ 0 inv # inv

150

250

revision

200

300

20

revision

30

40

350

50

shweet: # classes and invariants

10

classes w/ inv 100 # inv

Dafny: # classes and invariants

60

400

70 60 50 40 30 20

200 150 100 50 0 35 30 25 20 15 10 5 0

52

# classes or invariants

classes w/ 0inv # inv

10

20 revision

30

40

Labs: # classes and invariants

50

# classes or invariants

# classes or invariants

revision

200

300

5

10

revision

15

20

25

Logging: # classes and invariants

100

30

400

classes w/0inv # inv

# inv

classes 0 w/ inv

5

revision

400

600

10 revision

15

20

25

RCC: # classes and invariants

200

ESCJava: # classes and invariants

800

30

Fig. 31. Non-flat: # of classes, classes with invariants, invariant clauses (Java projects)

classes w/0inv # inv

classes w/0inv # inv

DirectVCGen: # classes and invariants 300 250 200 150

500 400 300

80

60

40

20

0

20

15

10

5

# classes or invariants # classes or invariants

100 50 80 60 40 20

# classes or invariants # classes or invariants

200 100 80 60 40 20 0

53 # inv

classes 0 w/ inv

# inv

classes 0 w/ inv 200 revision

300

50 revision

100

Umbra: # classes and invariants

100

JavaFE: # classes and invariants

150

400

# routines

# routines

500

50

100

revision

150

200

250

300

pre or post

pre post0

50

150

revision

200

250 pre or post

pre post0

200

400

800

revision

600

1000

1200

20

40 revision

60

80

100

120

GoboTime: Routines with some specification

pre or post

pre post0

EiffelBase: Routines with some specification

Fig. 32. Non-flat: # routines with specification (Eiffel projects)

100

GoboStructure: Routines with some specification

pre or post

pre post0

AutoTest: Routines with some specification

pre or post

pre post0

50 revision

100

150

200

50

revision

100

150

200

GoboUtility: Routines with some specification

pre or post

pre post0

EiffelProgramAnalysis: Routines with some specification

300 250 200

1200 1000 800 600

400

300

200

150

100

50

# routines # routines

400 200 200 150 100 50 0

# routines # routines

150 100 50 0 150 100 50 0

# routines # routines

300 200 100 0 1400 1000 800 600 400 200 0

54

pre or post

pre post0

100

200

400 revision

300

500

600

200

revision

400

600

800

GoboXML: Routines with some specification

pre or post

pre post0

GoboKernel: Routines with some specification

# routines

2000

1500

1000

500

0

pre post0

400

revision

600

800

100

200

300

Quickgraph: Routines with some specification

pre 200 post pre or post

Boogie: Routines with some specification

pre post0

20

40 revision

60

80

50 revision

100

Rxx: Routines with some specification

pre or post

pre post0

CCI: Routines with some specification

150

100

pre or post

pre or post

Fig. 33. Non-flat: # routines with specification (C# projects)

revision

50

0

# routines

250

200

150

200

100

12 10 8 6 4 2 0 1200 1000 800 600

# routines # routines

300 250 200 150

0

400

# routines # routines

pre or post

pre 0 post

150

250

revision

200

300

350

10

20

revision

30

40

50

shweet: Routines with some specification

pre 100 post pre or post

Dafny: Routines with some specification

60

400

250 200 150 100 50

100 50 0 10 8 6 4 2 0

55

# routines

pre or post

pre 0 post

10

20 revision

30

40

Labs: Routines with some specification

50

# routines

# routines

100

80

60

40

20

0

80

60

40

20

pre or post

pre 0 post

100

revision

200

300

5

15

revision

20

25

30

400

2000 pre or post

pre 0 post

200 revision

400

600

800

5

10 revision

15

20

25

RCC: Routines with some specification

pre or post

pre 0 post

ESCJava: Routines with some specification

Fig. 34. Non-flat: # routines with specification (Java projects)

10

Logging: Routines with some specification

pre or post

pre 0 post

DirectVCGen: Routines with some specification

# routines # routines

1500 1000 500 0 250 200 150 100 50

30

# routines # routines

800 600 400 200 6 5 4 3 2 1 0

56 pre or post

pre post0

100

200 revision

300

50 revision

100

Umbra: Routines with some specification

pre or post

pre post0

JavaFE: Routines with some specification

150

400

0.55

50

100

revision

150

200

250

300

inv

pre post0

100

150

revision

200

250

200

400

800

revision

600

1000

1200

inv

pre post0 20

40 revision

60

80

100

120

GoboTime: % routines and classes with specification

inv

pre post0

EiffelBase: % routines and classes with specification

Fig. 35. Non-flat: % routines and classes with specification (Eiffel projects)

50

GoboStructure: % routines and classes with specification

inv

pre post0

AutoTest: % routines and classes with specification

50 revision

100

150

200

inv

pre post0 50

revision

100

150

200

GoboUtility: % routines and classes with specification

inv

pre post0

EiffelProgramAnalysis: % routines and classes with specification 1.0 0.8

0.40 0.35 0.30

0.50

0.45

0.40

0.35

0.30

0.25

0.40

% routines or classes

% routines or classes

0.35

0.30

0.25

0.20

0.15

0.10

% routines or classes % routines or classes

0.25 0.20 0.15 0.6 0.5 0.4 0.3 0.2 0.1 0.0

% routines or classes % routines or classes

0.15 0.10 0.05 0.00 0.8 0.6 0.4 0.2 0.0

% routines or classes % routines or classes

0.6 0.4 0.2 0.0 0.4 0.3 0.2 0.1 0.0

57

100

200

400 revision

300

500

600

inv

pre post0

200

revision

400

600

800

GoboXML: % routines and classes with specification

inv

pre post0

GoboKernel: % routines and classes with specification

0.7

0.6

0.5

0.4

0.3

0.2

0.1

0.20

0.15

0.10

200

400

revision

600

800

pre post0

100

200

300

Quickgraph: % routines and classes with specification

pre post inv

Boogie: % routines and classes with specification

inv

inv

pre post0

inv

pre post0 40 revision

60

80

100

50 revision

100

150

Rxx: % routines and classes with specification

20

CCI: % routines and classes with specification

Fig. 36. Non-flat: % routines and classes with specification (C# projects)

revision

0.05

0.00

% routines or classes

% routines or classes

0.05 0.04

0.6 0.5 0.4 0.3 0.2

0.03 0.02 0.01 0.00 0.8 0.6 0.4

% routines or classes % routines or classes 0.2 0.0

% routines or classes % routines or classes

pre 0 post inv

100

150

250

revision

200

300

350

400

10

20

revision

30

40

50

60

shweet: % routines and classes with specification

pre post inv

Dafny: % routines and classes with specification 0.40 0.35 0.30 0.25 0.20 0.15 0.10

0.1 0.0 0.4 0.3 0.2 0.1 0.0

58

% routines or classes

inv

pre 0 post

10

20 revision

30

40

50

Labs: % routines and classes with specification

0.3

100

revision

200

300

400

inv

pre 0 post

10

15

revision

20

25

30

0.7 inv

pre 0 post

inv

pre 0 post revision

400

600

800

5

10 revision

15

20

25

30

RCC: % routines and classes with specification

200

ESCJava: % routines and classes with specification

Fig. 37. Non-flat: % routines and classes with specification (Java projects)

5

Logging: % routines and classes with specification

inv

pre 0 post

DirectVCGen: % routines and classes with specification 0.7 0.6 0.5

0.6 0.5 0.4 0.3

0.2

0.1

0.0

% routines or classes

% routines or classes

0.35

0.30

0.25

0.20

0.15

0.10

0.05

% routines or classes % routines or classes

0.2 0.1 0.5 0.4 0.3 0.2 0.1

% routines or classes % routines or classes

0.4 0.3 0.2 0.1 0.08 0.06 0.04 0.02 0.00

59 inv

100

200 revision

300

400

50 revision

100

150

Umbra: % routines and classes with specification

pre post0

inv

pre post0

JavaFE: % routines and classes with specification

400

50

100

revision

150

200

250

300

inv

pre post0

100

150

revision

200

250

200

400

800

revision

600

1000

1200

inv

pre post0 20

40 revision

60

80

100

120

GoboTime: Routines and classes with specification

inv

pre post0

EiffelBase: Routines and classes with specification

Fig. 38. Non-flat: # routines and classes with specification (Eiffel projects)

50

GoboStructure: Routines and classes with specification

inv

pre post0

AutoTest: Routines and classes with specification

800 600

50 revision

100

150

200

inv

pre post0 50

revision

100

150

200

GoboUtility: Routines and classes with specification

inv

pre post0

EiffelProgramAnalysis: Routines and classes with specification 300 250 200 150

300

200

100

# routines or classes

# routines or classes

120

100

80

60

40

20

# routines or classes # routines or classes

400 200 0 200 150 100 50 0

# routines or classes # routines or classes

150 100 50 0 120 100 80 60 40 20 0

# routines or classes # routines or classes

100 50 0 1000 800 600 400 200 0

60

100

200

400 revision

300

500

600

inv

pre post0

200

revision

400

600

800

GoboXML: Routines and classes with specification

inv

pre post0

GoboKernel: Routines and classes with specification

# routines or classes

1400

800 1000

600

400

200

0

250

200

150

100

200

400

revision

600

800

pre post0

100

200

300

Quickgraph: Routines and classes with specification

pre post inv

Boogie: Routines and classes with specification

pre post0

inv

pre post0 40 revision

60

80

50 revision

100

150

100

Rxx: Routines and classes with specification

20

CCI: Routines and classes with specification

inv

inv

Fig. 39. Non-flat: # routines and classes with specification (C# projects)

revision

50

0

# routines or classes

12 10 8 6 4 2 0 1000 800 600 200

400

# routines or classes # routines or classes

250 200

0

pre 0 post inv

100

150

250

revision

200

300

350

400

10

20

revision

30

40

50

60

shweet: Routines and classes with specification

pre post inv

Dafny: Routines and classes with specification

150 100 50

150 100 50 0 8 6 4

# routines or classes # routines or classes 2 0

61

# routines or classes

inv

pre 0 post

10

20 revision

30

40

50

Labs: Routines and classes with specification

100

80

60

40

20

0

# routines or classes

# routines or classes

60

50

40

30

20

10

0

inv

100

revision

200

300

400

10

15

revision

20

25

30

2000 1500 inv

pre 0 post

inv

pre 0 post revision

400

600

800

5

10 revision

15

20

25

30

RCC: Routines and classes with specification

200

ESCJava: Routines and classes with specification

Fig. 40. Non-flat: # routines and classes with specification (Java projects)

5

Logging: Routines and classes with specification

pre 0 post

inv

pre 0 post

DirectVCGen: Routines and classes with specification

# routines or classes # routines or classes

1000 500 0 200 150 100 50 0

# routines or classes # routines or classes

800 600 400 200 4 3 2 1 0

62 inv

100

200 revision

300

400

50 revision

100

150

Umbra: Routines and classes with specification

pre post0

inv

pre post0

JavaFE: Routines and classes with specification

50

100

revision

150

200

250

300

inv

pre post0

100

150

revision

200

250

200

400

800

revision

600

1000

1200

inv

pre post0 20

40 revision

60

80

100

120

GoboTime: Specification clauses per routine or class

inv

pre post0

EiffelBase: Specification clauses per routine or class

Fig. 41. Non-flat: Specification clauses per routine or class (Eiffel projects)

50

GoboStructure: Specification clauses per routine or class

inv

pre post0

AutoTest: Specification clauses per routine or class

0.8 0.6

50 revision

100

150

200

inv

pre post0 50

revision

100

150

200

GoboUtility: Specification clauses per routine or class

inv

pre post0

EiffelProgramAnalysis: Specification clauses per routine or class 0.20 0.15 0.10

1.0 0.8 0.6

1.5

1.0

0.5

# clauses per routine or class

# clauses per routine or class

1.2

1.0

0.8

0.6

0.4

0.2

# clauses per routine or class # clauses per routine or class

0.4 0.2 1.0 0.5 0.0

# clauses per routine or class # clauses per routine or class

0.05 0.00 1.5 1.0 0.5 0.0

# clauses per routine or class # clauses per routine or class

0.4 0.2 0.0 1.2 1.0 0.8 0.6 0.4 0.2 0.0

63

100

200

400 revision

300

500

600

inv

pre post0

200

revision

400

600

800

GoboXML: Specification clauses per routine or class

inv

pre post0

GoboKernel: Specification clauses per routine or class

3.0

2.5

200

400

revision

600

800

inv

pre post0

200

revision

300 inv

pre post0

inv

pre post0 40 revision

60

80

100

50 revision

100

150

Rxx: Specification clauses per routine or class

20

CCI: Specification clauses per routine or class

Fig. 42. Non-flat: Specification clauses per routine or class (C# projects)

100

Quickgraph: Specification clauses per routine or class

pre post inv

Boogie: Specification clauses per routine or class 0.06 0.05 0.04 0.03

2.0

1.5

1.0

0.5

# clauses per routine or class

# clauses per routine or class

0.0

0.3

0.2

0.1

0.0

# clauses per routine or class # clauses per routine or class

0.02 0.01 0.00 2.0 1.5 1.0 0.5 0.0

# clauses per routine or class # clauses per routine or class

pre 0 post inv

100

150

250

revision

200

300

350

400

10

20

revision

30

40

50

60

shweet: Specification clauses per routine or class

pre post inv

Dafny: Specification clauses per routine or class 1.0 0.8 0.6 0.4 0.2

1.5 1.0 0.5 0.0 0.6 0.5 0.4 0.3 0.2 0.1 0.0

64

# clauses per routine or class

inv

pre 0 post

10

20 revision

30

40

50

Labs: Specification clauses per routine or class

100

revision

200

300

400

inv

pre 0 post

10

15

revision

20

25

30 inv

pre 0 post

inv

pre 0 post revision

400

600

800

5

10 revision

15

20

25

30

RCC: Specification clauses per routine or class

200

ESCJava: Specification clauses per routine or class

Fig. 43. Non-flat: Specification clauses per routine or class (Java projects)

5

Logging: Specification clauses per routine or class

inv

pre 0 post

0.8 0.6

DirectVCGen: Specification clauses per routine or class 2.5 2.0 1.5

0.3

0.2

0.1

0.0

# clauses per routine or class

# clauses per routine or class

0.6

0.5

0.4

0.3

0.2

0.1

# clauses per routine or class # clauses per routine or class

0.4 0.2 0.5 0.4 0.3 0.2 0.1

# clauses per routine or class # clauses per routine or class

1.0 0.5 0.15 0.10 0.05 0.00

65 inv

100

200 revision

300

400

50 revision

100

150

Umbra: Specification clauses per routine or class

pre post0

inv

pre post0

JavaFE: Specification clauses per routine or class

inv

pre post0

50

100

revision

150

200

250

300

# clauses per routine or class

inv

pre post0 200

400

800

revision

600

1000

1200 inv

pre post0 50 revision

100

150

200 inv

pre post0

100

200

400 revision

300

500

600

EiffelBase: Average specification strength per routine or class EiffelProgramAnalysis: Average specification strength per routine or GoboKernel: class Average specification strength per routine or class

# clauses per routine or class

AutoTest: Average specification strength per routine or class

# clauses per routine or class

50

100

150

revision

200

250 inv

pre post0 20

40

60 revision

80

100

120

# clauses per routine or class

# clauses per routine or class

3.5

3.0

2.5

2.0

1.5

3.0 2.5 2.0 1.5 1.0

6 5 4 3 2 1 0

0.5 0.0

# clauses per routine or class

Fig. 44. Non-flat: Average specification strength per routine or class (Eiffel projects)

inv

pre post0 inv

pre post0 50

revision

100

150

200

# clauses per routine or class

inv

pre post0

200

revision

400

600

800

GoboStructure: Average specification strength per routine or classGoboTime: Average specification strength per routine or class GoboUtility: Average specification strength per routine or class GoboXML: Average specification strength per routine or class

# clauses per routine or class

3.5

3.0

2.5

2.0

1.5

2.6 2.4 2.2 2.0 1.8 1.6 1.4 1.2

1.2 1.0 0.8 0.6 0.4 0.2 0.0

3.0 2.5 2.0 1.5 1.0 0.5 0.0 2.5 2.0 1.5 1.0 0.5 0.0

66

# clauses per routine or class

200

400

revision

600

800

inv

100

200

revision

300

20

40 revision

60

80

100

inv

pre post0 50 revision

100

150

Rxx: Average specification strength per routine or class

inv

pre post0

Fig. 45. Non-flat: Average specification strength per routine or class (C# projects)

pre post0

Quickgraph: Average specification strength per routine or class

pre post inv

CCI: Average specification strength per routine or class 2.0

Boogie: Average specification strength per routine or class

5

4

100

150

250

revision

200

300

350

400

inv

pre 0 post 10

20

revision

30

40

50

60

shweet: Average specification strength per routine or class

pre post inv

Dafny: Average specification strength per routine or class 3.0 2.5 2.0 1.5 1.0

1.5 1.0 0.5

3

2

1

2.0

1.5

1.0

0.5

0.0

# clauses per routine or class

# clauses per routine or class # clauses per routine or class

0.0 8 6 4 2 0

# clauses per routine or class # clauses per routine or class

inv

pre 0 post

10

20 revision

30

40

50

Labs: Average specification strength per routine or class 2.4 2.2 2.0 1.8 1.6 1.4 1.2

0.5 0.0 2.0 1.5 1.0 0.5 0.0

67

# clauses per routine or class

100

revision

200

300

400

inv

5

10

15

revision

20

25

30

200 revision

400

600

800

inv

pre 0 post 5

10 revision

15

20

25

30

RCC: Average specification strength per routine or class

inv

pre 0 post

Fig. 46. Non-flat: Average specification strength per routine or class (Java projects)

pre 0 post

Logging: Average specification strength per routine or class

inv

pre 0 post

DirectVCGen: Average specification strength per routine or class ESCJava: Average specification strength per routine or class

# clauses per routine or class

2.0

1.5

1.0

0.5

0.0

2.0

100

200 revision

300

400

inv

pre post0

50 revision

100

150

Umbra: Average specification strength per routine or class

inv

pre post0

JavaFE: Average specification strength per routine or class 5 4

3.5 3.0 2.5 2.0 1.5

1.8

1.6

1.4

1.2

1.0

# clauses per routine or class

# clauses per routine or class # clauses per routine or class

1.0 6 5 4 3 2 1

# clauses per routine or class # clauses per routine or class

3 2 2.0 1.5 1.0 0.5 0.0

68

# routines

# routines

6

5

4

3

2

1

0

6

100

150

revision

200

250

300

inv strong

pre weak pre strong post weak post strong 0 inv weak

50

150

revision

200

250

400

800

revision

600

1000

1200

pre weak pre strong post weak post strong 20 inv 0 weak inv strong 40 revision

60

80

100

GoboTime: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong 0 200 inv weak

EiffelBase: Weakening and strengthening

Fig. 47. Non-flat: Weakening and strengthening (Eiffel projects)

100

GoboStructure: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong 0 50 inv weak

AutoTest: Weakening and strengthening 30 25 20 15 10 5 0 2.0 1.5 1.0

5

4

3

2

1

0

# routines # routines

120

3.0 2.5 2.0 1.5 1.0 0.5 0.0

50

100 revision

150

200

pre weak pre strong post weak post strong 0 inv weak 50

100

150

200

GoboUtility: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong 0 inv weak

EiffelProgramAnalysis: Weakening and strengthening

inv strong

revision

6 5 4 3 2 1

# routines # routines

8 6 4 2 0 14

0

0.5 0.0

# routines # routines

12 10 8 6 4 2 0

69

200

400 revision

300

500

600

inv strong

pre weak pre strong post weak post strong 0 inv weak

200

revision

400

600

800

GoboXML: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong 0 100 inv weak

GoboKernel: Weakening and strengthening

# routines

# routines

400

revision

600

800

inv strong

pre weak pre strong post weak post strong 0 inv weak

100

300

pre weak pre strong post weak post strong inv 0 weak inv strong

pre weak pre strong post weak post strong inv 0weak inv strong 40 revision

60

80

50 revision

100

Rxx: Weakening and strengthening

20

CCI: Weakening and strengthening

Fig. 48. Non-flat: Weakening and strengthening (C# projects)

revision

200

Quickgraph: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong inv weak 200

Boogie: Weakening and strengthening

150

100

8 6

3.0 2.5 2.0 1.5

250

200

150

100

50

0

120

100

80

60

40

20

0

# routines # routines

1.0 0.5 0.0 12 10 8 6 4 2 0

# routines # routines

150

250

revision

200

300

350

20

revision

30

40

50

shweet: Weakening and strengthening

pre weak pre strong post weak post strong 10 inv0weak inv strong

inv strong

pre weak pre strong post weak post strong inv weak 100

Dafny: Weakening and strengthening

60

400

40 30 20 10 0

4 2 0 2.0 1.5 1.0 0.5 0.0

70

# routines

pre weak pre strong post weak post strong inv0weak inv strong 10

20 revision

30

40

Labs: Weakening and strengthening

50

# routines

# routines

100

200

revision

300

pre weak pre strong post weak post strong 5 inv0 weak inv strong

15

revision

20

25

30

400

200 revision

400

600

800

10 revision

15

20

25

RCC: Weakening and strengthening

pre weak pre strong post weak post strong inv0 weak 5 inv strong

pre weak pre strong post weak post strong inv 0weak inv strong

ESCJava: Weakening and strengthening

Fig. 49. Non-flat: Weakening and strengthening (Java projects)

10

Logging: Weakening and strengthening

pre weak pre strong post weak post strong inv0 weak inv strong

DirectVCGen: Weakening and strengthening 300 250 200

30

70 60 50

10

8

6

4

2

0

20

15

10

5

0

# routines # routines

150 100 50 0 200 150 100 50 0

# routines # routines

40 30 20 10 0 1.0 0.8 0.6 0.4 0.2 0.0

71

100

200 revision

300

50 revision

100

Umbra: Weakening and strengthening

pre weak pre strong post weak post strong inv 0 weak inv strong

inv strong

pre weak pre strong post weak post strong 0 inv weak

JavaFE: Weakening and strengthening

150

400

% routines

% routines

0.60

0.55

0.50

0.45

0.40

0.8

0.7

0.6

0.5

0.4

0.3

0.2

100

150

revision

200

250

300

50

100

150

revision

200

250

400

800

revision

600

1000

1200

0 20 public non−public

40

60

80

100

GoboTime: % routines with pre or post

0 200 public non−public

EiffelBase: % routines with pre or post

revision

120

Fig. 50. Non-flat: % routines with specification: public vs nonpublic (Eiffel projects)

0 public non−public

GoboStructure: % routines with pre or post

0 50 public non−public

AutoTest: % routines with pre or post

0.4 0.3 0.2 0.1 1.0 0.8 0.6 0.2

% routines % routines

0.30 0.25 0.20

0.0

0.4

% routines % routines

0.15 0.10 0.05 0.00 1.0 0.8 0.6 0.4 0.2 0.0

50

100 revision

150

0 public non−public

50

revision

100

150

200

200

GoboUtility: % routines with pre or post

0 public non−public

EiffelProgramAnalysis: % routines with pre or post

% routines % routines

1.0 0.8 0.6 0.4 0.2 0.0 0.6 0.5 0.4 0.3 0.2 0.1 0.0

72

200

400 revision

300

500

600

0 public non−public

200

revision

400

600

800

GoboXML: % routines with pre or post

0 100 public non−public

GoboKernel: % routines with pre or post

% routines

% routines

0.80

0.75

0.70

0.65

0.60

0.55

0.50

0.45

0.20

0.15

400

revision

600

800

0 public non−public

100

200

300

Quickgraph: % routines with pre or post

200 public non−public

Boogie: % routines with pre or post 0.12 0 public non−public

0 public non−public

40 revision

60

80

50 revision

100

Rxx: % routines with pre or post

20

CCI: % routines with pre or post

150

100

Fig. 51. Non-flat: % routines with specification: public vs nonpublic (C# projects)

revision

0.05

0.7 0.6 0.5

0.10 0.08

0.00

0.10

% routines % routines

0.06 0.04 0.02 0.00 1.0 0.8 0.6 0.4 0.2 0.0

% routines % routines

150

250

revision

200

300

350

0 10 public non−public

20

revision

30

40

50

shweet: % routines with pre or post

public 100 non−public

Dafny: % routines with pre or post

60

400

0.50 0.45 0.40 0.35

0.4 0.3 0.2 0.4 0.3 0.2 0.1 0.0

73

% routines

0 public non−public

10

20 revision

30

40

Labs: % routines with pre or post

50

% routines

% routines

100

200

revision

300

15

revision

20

25

30

400

0 5 public non−public

0 public non−public revision

400

600

10 revision

15

20

25

RCC: % routines with pre or post

200

800

ESCJava: % routines with pre or post

30

Fig. 52. Non-flat: % routines with specification: public vs nonpublic (Java projects)

10

Logging: % routines with pre or post

0 5 public non−public

0 public non−public

DirectVCGen: % routines with pre or post 0.7 0.6 0.5

0.3

0.2

0.1

0.0

0.5

0.4

0.3

0.2

0.1

% routines % routines

0.4 0.3 0.2 0.6 0.5 0.4 0.3 0.2 0.1

% routines % routines

0.8 0.7 0.6 0.5 0.4 0.25 0.20 0.15 0.10 0.05 0.00

74 0 public non−public

0 public non−public

200 revision

300

50 revision

100

Umbra: % routines with pre or post

100

JavaFE: % routines with pre or post

150

400

15

10

5

0

# classes

−A weak

+A same +A strong +A weak −A same 0 −A strong

50

100

150

revision

200

250

300 −A weak

+A same +A strong +A weak −A same 0 200 −A strong 400

800

revision

600

1000

1200

50

100

150

revision

200

250

+A same +A strong +A weak −A same −A 0 strong −A weak 20

40

60 revision

80

100

120

Fig. 53. Non-flat: Weakening and strengthening of class invariants (Eiffel projects)

−A weak

+A same +A strong +A weak −A same 0 −A strong

50

100 revision

150

200

−A weak

+A same +A strong +A weak −A same 0 −A strong 50

revision

100

150

200

GoboUtility: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same 0 −A strong

200

400 revision

300

500

600

−A weak

+A same +A strong +A weak −A same 0 −A strong

200

revision

400

600

800

GoboXML: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same 0 100 −A strong

EiffelBase: Weakening and strengthening of class invariants EiffelProgramAnalysis: Weakening and strengthening of class invariants GoboKernel: Weakening and strengthening of class invariants

GoboStructure: Weakening and strengthening of class invariants GoboTime: Weakening and strengthening of class invariants

# classes

15

10

5

0

14 12 10 8 6 4 2 0

3.0 2.5

AutoTest: Weakening and strengthening of class invariants

# classes # classes

3.0 2.5 2.0 1.5 1.0 0.5 0.0

2.0 1.5 1.0 0.5

2.0 1.5 1.0 0.5 0.0 1.0 0.8 0.6 0.4 0.2 0.0

# classes # classes

# classes # classes

0.0 12 10 8 6 4 2 0

75

# classes

400

revision

600

800

100

200

revision

300

1.0

20

40 revision

60

80

100

+A same +A strong +A weak −A same −A 0 strong −A weak 50 revision

100

150

Rxx: Weakening and strengthening of class invariants

+A same +A strong +A weak −A same −A 0strong −A weak

CCI: Weakening and strengthening of class invariants

Fig. 54. Non-flat: Weakening and strengthening of class invariants (C# projects)

−A weak

+A same +A strong +A weak −A same 0 −A strong

Quickgraph: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same −A strong200

Boogie: Weakening and strengthening of class invariants

1.0

0.5

150

250

revision

200

300

350

400

+A same +A strong +A weak −A same −A0strong −A weak 10

20

revision

30

40

50

60

shweet: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same −A strong100

Dafny: Weakening and strengthening of class invariants 1.0 0.5 0.0

0.5 0.0 −0.5

0.0

−0.5

−1.0

1.0

0.5

0.0

−0.5

−1.0

# classes

# classes # classes

−1.0 1.0 0.5 0.0 −0.5 −1.0

# classes # classes

1.0 0.5 0.0 −0.5 −1.0

−0.5 −1.0 1.0 0.5 0.0 −0.5 −1.0

76

# classes

+A same +A strong +A weak −A same −A0strong −A weak 10

20 revision

30

40

50

Labs: Weakening and strengthening of class invariants

# classes

# classes

100

200

revision

300

400

5

10

15

revision

20

25

30

200 revision

400

600

800

+A same +A strong +A weak −A same −A0 strong −A weak 5

10 revision

15

20

25

30

RCC: Weakening and strengthening of class invariants

+A same +A strong +A weak −A same −A 0strong −A weak

ESCJava: Weakening and strengthening of class invariants

Fig. 55. Non-flat: Weakening and strengthening of class invariants (Java projects)

+A same +A strong +A weak −A same −A0 strong −A weak

Logging: Weakening and strengthening of class invariants

+A same +A strong +A weak −A same −A0 strong −A weak

DirectVCGen: Weakening and strengthening of class invariants 1.0 0.5

100

200 revision

300

400

−A weak

+A same +A strong +A weak −A same 0 −A strong 50

revision

100

150

Umbra: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same 0 −A strong

JavaFE: Weakening and strengthening of class invariants 1.0 0.5

1.0

0.5

0.0

−0.5

−1.0

1.0

0.5

0.0

−0.5

−1.0

# classes # classes

0.0 −0.5 −1.0 1.0 0.5 0.0 −0.5 −1.0

# classes # classes

0.0 −0.5 −1.0 1.0 0.5 0.0 −0.5 −1.0

77

12

Flat classes

The following pages show the plots for the 21 projects of our study, considering flat classes.

78

# routines

# routines

25

revision

150

200

250

300

spec

body+spec 0 (nonempty 50 spec) 100 body revision

150

200

300

800

revision

600

1000

1200

spec

body+spec 0 (nonempty 20 spec) 40 body revision

60

80

100

120

GoboTime: # changed routines (for nonempty spec)

spec

body+spec 200 spec) 400 body0 (nonempty

EiffelBase: # changed routines (for nonempty spec)

revision

100

150

200

body+spec 0 (nonempty 50 body spec) spec

revision

100

150

200

GoboUtility: # changed routines (for nonempty spec)

body+spec 0 (nonempty spec) 50 body spec

EiffelProgramAnalysis: # changed routines (for nonempty spec)

Fig. 56. Flat: Changed routines (with nonempty unchanged spec) (Eiffel projects)

250

GoboStructure: # changed routines (for nonempty spec)

spec

body+spec 0 (nonempty 50 spec)100 body

AutoTest: # changed routines (for nonempty spec) 70 60 50 40

35 30 25 20

20

15

10

5

0

200

150

100

50

0

# routines # routines

200 100 0 20 15 10 5 0

# routines # routines

30 20 10 0 12 10 8 6 4 2 0

# routines # routines

15 10 5 0 1500 1000 500 0

79

400 revision

300

500

600

body+spec body0 (nonempty200 spec) spec

revision

400

600

800

GoboXML: # changed routines (for nonempty spec)

spec

body+spec 0 (nonempty 100 spec) 200 body

GoboKernel: # changed routines (for nonempty spec)

# routines

200

150

100

50

0

120

100

80

400 revision

600

800

body+spec 0 (nonempty spec) 100 body spec 200

300

Quickgraph: # changed routines (for nonempty spec)

spec

body+spec 200 body (nonempty spec)

Boogie: # changed routines (for nonempty spec)

revision

40 revision

60

80

body+spec 0 (nonempty spec) 50 body spec revision

100

150

100

Rxx: # changed routines (for nonempty spec)

body+spec 0 (nonempty 20spec) body spec

CCI: # changed routines (for nonempty spec)

250

revision

200

300

350

400

spec

body+spec 0 (nonempty 10 spec) 20 body

revision

30

40

50

60

shweet: # changed routines (for nonempty spec)

spec

body+spec 100 150 body (nonempty spec)

Dafny: # changed routines (for nonempty spec)

Fig. 57. Flat: Changed routines (with nonempty unchanged spec) (C# projects)

40

20

# routines

2.0 1.5

70 60 50 40 30 20

1.0 0.5 0.0 150 100

0

60

# routines # routines 50 0

# routines # routines

140 120 100 80 60 40 20 0

10 0 2.0 1.5 1.0 0.5 0.0

80

# routines

spec

body+spec 0 (nonempty 10 spec) body

20 revision

30

40

50

Labs: # changed routines (for nonempty spec)

20 15 10

# routines

30 20 10

200 revision

300

400

Logging: # changed routines (for nonempty spec)

body+spec 0 (nonempty 100 body spec) spec

body+spec 0 (nonempty 5 spec)10 body 15

20

25

30

30 25

0

300 spec

body+spec 0 (nonempty 5 body spec)10 spec

revision

400

600

800

revision

15

20

25

30

RCC: # changed routines (for nonempty spec)

body+spec 0 (nonempty200 body spec) spec

ESCJava: # changed routines (for nonempty spec)

200 revision

300

400

body+spec 0 (nonempty spec)50 body spec

revision

100

150

Umbra: # changed routines (for nonempty spec)

body+spec 0 (nonempty spec) 100 body spec

JavaFE: # changed routines (for nonempty spec)

Fig. 58. Flat: Changed routines (with nonempty unchanged spec) (Java projects)

revision

5

300 250 200

250 200 150 100 50 0 600

0

# routines

DirectVCGen: # changed routines (for nonempty spec)

# routines # routines

500 400 300 200 100 0

# routines # routines

150 100 50 0 20 15 10 5 0

81

# routines

# routines

25

100

150 revision

200

250

300

0 body+spec spec

50

100 revision

150

250

300

400

800

revision

600

1000

1200

0 20 body+spec spec

40 revision

60

80

100

120

GoboTime: # changed routines (w/ or w/o body change)

0 200 body+spec spec

EiffelBase: # changed routines (w/ or w/o body change)

50

100 revision

150

200

0 body+spec spec

50

revision

100

150

200

GoboUtility: # changed routines (w/ or w/o body change)

0 body+spec spec

200

400 revision

300

500

600

0 body+spec spec

200

revision

400

600

800

GoboXML: # changed routines (w/ or w/o body change)

0 100 body+spec spec

EiffelProgramAnalysis: # changed routines (w/ or w/o body change) GoboKernel: # changed routines (w/ or w/o body change)

Fig. 59. Flat: Routines with changed specification (with or without body changing) (Eiffel projects)

200

GoboStructure: # changed routines (w/ or w/o body change)

0 50 body+spec spec

AutoTest: # changed routines (w/ or w/o body change) 70 60 50 40

35 30 25 20

20

15

10

5

0

200

150

100

50

0

# routines # routines

200 100 0 14 12 10 8 6 4 2 0

# routines # routines

30 20 10 0 10 8 6 4 2 0

# routines # routines

15 10 5 0 1500 1000 500 0

82

# routines

# routines

200

150

100

50

200 body+spec spec

400 revision

600

800

Boogie: # changed routines (w/ or w/o body change)

0 body+spec spec

100 revision

200

2.0 1.5

20

40 revision

60

80

100

0 body+spec spec

50 revision

100

150

Rxx: # changed routines (w/ or w/o body change)

0 body+spec spec

CCI: # changed routines (w/ or w/o body change)

150

250

revision

200

300

350

400

0 10 body+spec spec

20

revision

30

40

50

60

shweet: # changed routines (w/ or w/o body change)

100 body+spec spec

Dafny: # changed routines (w/ or w/o body change)

Fig. 60. Flat: Routines with changed specification (with or without body changing) (C# projects)

300

Quickgraph: # changed routines (w/ or w/o body change)

0

120

100

80

60

40

20

0

# routines # routines

70 60 50 40 30 20

1.0 0.5 0.0 15 10 5 0

# routines # routines

140 120 100 80 60 40 20 0

10 0 2.0 1.5 1.0 0.5 0.0

83

# routines

0 body+spec spec

10

20 revision

30

40

50

Labs: # changed routines (w/ or w/o body change)

# routines

8 6 4 2 0

100

200 revision

300

400

Logging: # changed routines (w/ or w/o body change)

0 body+spec spec

0 5 body+spec spec

10

15

20

25

30

30 25 20 15 10

200 revision

400

600

800

0 5 body+spec spec

10

revision

15

20

25

30

RCC: # changed routines (w/ or w/o body change)

0 body+spec spec

ESCJava: # changed routines (w/ or w/o body change)

100

200 revision

300

400

0 body+spec spec

50 revision

100

150

Umbra: # changed routines (w/ or w/o body change)

0 body+spec spec

JavaFE: # changed routines (w/ or w/o body change)

Fig. 61. Flat: Routines with changed specification (with or without body changing) (Java projects)

revision

5 0

# routines

300 250 200 150 100 50 0 600

300 250 200

DirectVCGen: # changed routines (w/ or w/o body change)

# routines # routines

500 400 300 200 100 0

# routines # routines

150 100 50 0 20 15 10 5 0

84

# routines

# routines

80

60

40

20

0

revision

150

200

250

300

spec

body+spec body 0 (nonempty 50 spec) 100 body revision

150

200

250

GoboStructure: # changed routines (types of change)

spec

body+spec body 0 (nonempty 50 spec)100 body

AutoTest: # changed routines (types of change) 700 600 500 400 300 200 100 0 30 25 20

400

300

200

100

0

# routines

800

revision

600

1000

1200

spec

body+spec body 0 (nonempty 20 spec) 40 body revision

60

80

100

120

GoboTime: # changed routines (types of change)

spec

body+spec body 200 spec) 400 body0 (nonempty

EiffelBase: # changed routines (types of change)

revision

100

150

200

body+spec body 0 (nonempty 50 body spec) spec

100

150

200

GoboUtility: # changed routines (types of change)

body+spec body 0 (nonempty spec) 50 body spec

EiffelProgramAnalysis: # changed routines (types of change)

revision

Fig. 62. Flat: changed routines (types of change) (Eiffel projects)

# routines

250 200 150 100 50 0 20 15 10 5

# routines # routines

50 40 30 20 10 0 1500 1000 0

15 10 5 0

# routines # routines

500 0

85

400 revision

300

500

600

body+spec body body0 (nonempty200 spec) spec

revision

400

600

800

GoboXML: # changed routines (types of change)

spec

body+spec body 0 (nonempty 100 spec) 200 body

GoboKernel: # changed routines (types of change)

# routines

# routines

400 revision

600

800

body+spec body 0 (nonempty spec) 100 body spec revision

200

300

Quickgraph: # changed routines (types of change)

spec

body+spec body 200 body (nonempty spec)

Boogie: # changed routines (types of change) 10 8 6

200

150

100

50

0

120

100

80

60

40

20

0

# routines

40 revision

60

80

body+spec body 0 (nonempty spec) 50 body spec revision

100

Rxx: # changed routines (types of change)

body+spec body 0 (nonempty 20spec) body spec

CCI: # changed routines (types of change)

150

100

spec

250

revision

200

300

350

revision

30

40

50

shweet: # changed routines (types of change)

body+spec body 0 (nonempty 10 spec) 20 body

spec

body+spec body 100 150 body (nonempty spec)

Dafny: # changed routines (types of change)

Fig. 63. Flat: changed routines (types of change) (C# projects)

# routines

70 60 50 40 30 20

4 2 0 150 100 50 0

# routines # routines

60

400

140 120 100 80 60 40 20 0

10 0 25 20 15 10 5 0

86

# routines

spec

body+spec body 0 (nonempty 10 spec) body

20 revision

30

40

Labs: # changed routines (types of change)

50

100 20 15 10

300

Logging: # changed routines (types of change)

revision

200

30

400 revision

400

600

800

body+spec body 0 (nonempty 5 spec)10 body 15

20

25

body+spec body 0 (nonempty 5 body spec)10

15

20

25

RCC: # changed routines (types of change)

body+spec body 0 (nonempty200 body spec) spec

30

ESCJava: # changed routines (types of change)

spec revision

revision

200 revision

300

body+spec body 0 (nonempty spec)50 body spec

revision

100

400

150

Umbra: # changed routines (types of change)

body+spec body 0 (nonempty spec) 100 body spec

JavaFE: # changed routines (types of change)

Fig. 64. Flat: changed routines (types of change) (Java projects)

spec

5 0

# routines

80 60 40 20 30 25

0

300 250 200 150 100 50 0 600 500 400 300 200 100 0

# routines

body+spec body 0 (nonempty 100 body spec) spec

# routines # routines

300 250 200 150 100 50 140

0

DirectVCGen: # changed routines (types of change)

# routines # routines

120 100 80 60 40 20 0

87

4

3

2

1

0

20

15

10

5

0

100 revision

150

200

250

% inv mean inv # inv0 weak 50 # inv strong 100 revision

150

200

300

400

800

revision

600

1000

40 revision

60

80

1200

100

GoboTime: Average and % inv

% inv mean inv 0 weak 20 # inv # inv strong

% inv mean inv # inv0 weak 200 # inv strong

EiffelBase: Average and % inv

120

% inv mean inv 0 weak # inv # inv strong

% inv mean inv 0 weak # inv # inv strong revision

100

150

50

revision

100

150

GoboUtility: Average and % inv

50

200

200

EiffelProgramAnalysis: Average and % inv

Fig. 65. Flat: Average invariant strength and % of classes with invariant (Eiffel projects)

250

GoboStructure: Average and % inv

% inv mean inv # inv0 weak 50 # inv strong

AutoTest: Average and % inv 40 30 20 10 0 5 4 3 2 1 0

1.2 1.0 0.8 0.6 0.4 0.2 0.0 3.0 2.5 2.0 1.5 1.0 0.5 0.0

12 10 8 6 4 2 0 150 100 50 0

88

% inv mean inv # inv0 weak # inv strong

% inv mean inv # inv0 weak 100 # inv strong

400 revision

300

500

200

revision

400

600

GoboXML: Average and % inv

200

600

800

GoboKernel: Average and % inv

35

30

25

20

15

10

5

0

2.0

1.5

% inv mean inv # inv0 weak # inv strong

# inv strong

% inv mean inv 200 # inv weak revision

600

100

200

300

Quickgraph: Average and % inv

400

Boogie: Average and % inv

800

revision

% inv mean inv 0 weak # inv # inv strong

% inv mean inv 0 weak # inv # inv strong 20 revision

60

50 revision

100

Rxx: Average and % inv

40

CCI: Average and % inv

80

150

100

% inv mean inv 0 weak 10 # inv # inv strong

# inv strong

% inv mean inv 100 # inv weak

250

revision

200

300

20

revision

30

40

shweet: Average and % inv

150

Dafny: Average and % inv

Fig. 66. Flat: Average invariant strength and % of classes with invariant (C# projects)

0.5

0.0

1.0

2.0 1.5 1.0 0.5 0.0 8 6 4 2 0

8 6

50

350

60

400

8 6 4 2 0

4 2 0 1.0 0.5 0.0 −0.5 −1.0

89

% inv mean inv 0 weak # inv # inv strong

10

20 revision

30

Labs: Average and % inv

40

50

2.0 1.5 1.0 0.5 0.0 2.0 1.5 1.0 0.5 0.0 % inv mean inv # 0inv weak 5 # inv strong

% inv mean inv #0 inv weak # inv strong revision

200

300

10

20

25

30

400

% inv mean inv #0 inv weak 5 # inv strong

% inv mean inv 0 weak # inv # inv strong revision

400

600

10

15

20

RCC: Average and % inv

200

ESCJava: Average and % inv

25

800

30 revision

% inv mean inv 0 weak # inv # inv strong

% inv mean inv # inv0 weak # inv strong

200 revision

300

50 revision

100

Umbra: Average and % inv

100

JavaFE: Average and % inv

Fig. 67. Flat: Average invariant strength and % of classes with invariant (Java projects)

revision

15

Logging: Average and % inv

100

DirectVCGen: Average and % inv

5 4 3 2 1 0 6 5 4 3 1 0

2

6 5 4 3 2 1 0 6 5 4 3 2 1 0

90

150

400

400

300

200

100

# classes or invariants

# classes or invariants

800

600

400

200

0

# inv

classes 0 w/ inv

# inv

classes 0 w/ inv 100 revision

150

200

250

50

100 revision

150

200

300

# inv

classes 0 w/ inv

# inv

classes 0 w/ inv 400

800

revision

600

1000

1200

20

40 revision

60

80

100

GoboTime: # classes and invariants

200

EiffelBase: # classes and invariants

120

classes 0 w/ inv

# inv

classes 0 w/ inv

revision

100

150

50

100

150

GoboUtility: # classes and invariants

50

200

200

EiffelProgramAnalysis: # classes and invariants

# inv

revision

Fig. 68. Flat: # of classes, classes with invariants, invariant clauses (Eiffel projects)

250

GoboStructure: # classes and invariants

50

AutoTest: # classes and invariants 1400 1200 1000 800 600 400 200 0 80 60

# classes or invariants # classes or invariants

200 150 100 50 0 60 50 40 30 20 10 0

# classes or invariants # classes or invariants

150 100 50 0 6000 5000 4000 3000 2000

40 20 0

# classes or invariants # classes or invariants

1000 0

91

# inv

classes 0 w/ inv

# inv

classes 0 w/ inv

200

400 revision

300

500

600

200

revision

400

600

800

GoboXML: # classes and invariants

100

GoboKernel: # classes and invariants

# inv

classes 0 w/ inv

400 revision

600

800

100 revision

200

300 # inv

classes 0 w/ inv

# inv

classes 0 w/ inv 40 revision

60

80

50 revision

100

Rxx: # classes and invariants

20

CCI: # classes and invariants

150

100

classes w/ 0 inv # inv

150

250

revision

200

300

20

revision

30

40

350

50

shweet: # classes and invariants

10

classes w/ inv 100 # inv

Dafny: # classes and invariants

Fig. 69. Flat: # of classes, classes with invariants, invariant clauses (C# projects)

Quickgraph: # classes and invariants

classes 200 w/ inv # inv

Boogie: # classes and invariants 100 80 60 40

300 250 200 150

800

600

400

200

0

# classes or invariants

# classes or invariants

300

250

200

150

100

50

0

# classes or invariants # classes or invariants

20 0 250 200 150 100 50 0

# classes or invariants # classes or invariants

60

400

100 80 60 40 20

100 50 0 35 30 25 20 15 10 5 0

92

# classes or invariants

classes w/ 0inv # inv

10

20 revision

30

40

Labs: # classes and invariants

50

# classes or invariants # classes or invariants

classes w/0inv # inv

classes w/0inv # inv 200 revision

300

5

10

20

25

30

400

classes w/0inv # inv

# inv

classes 0 w/ inv

5

revision

400

600

10

revision

15

20

25

RCC: # classes and invariants

200

ESCJava: # classes and invariants

800

30

# inv

classes 0 w/ inv

# inv

classes 0 w/ inv

200 revision

300

50 revision

100

Umbra: # classes and invariants

100

JavaFE: # classes and invariants

Fig. 70. Flat: # of classes, classes with invariants, invariant clauses (Java projects)

revision

15

Logging: # classes and invariants

100

DirectVCGen: # classes and invariants 300 250 200 150

500 400 300

80 60 40 20 0 20 15 10 5

# classes or invariants # classes or invariants

100 50 80 60 40 20

# classes or invariants # classes or invariants

200 100 80 60 40 20 0

93

150

400

# routines

# routines

50

100 revision

150

200

250

300

pre or post

pre post0 50

100 revision

150

200

250

GoboStructure: Routines with some specification

pre or post

pre post0

AutoTest: Routines with some specification 5000 4000 3000

1500

1000

500

2500

2000

1500

1000

500

# routines # routines

2000 1000 500 400 300 200 100 pre or post

pre post0

200

400

800

revision

600

1000

1200

20

40 revision

60

80

100

120

GoboTime: Routines with some specification

pre or post

pre post0

EiffelBase: Routines with some specification

pre post0

50

revision

100

150

200

50

100

150

200

GoboUtility: Routines with some specification

pre or post

pre post0

EiffelProgramAnalysis: Routines with some specification

pre or post

Fig. 71. Flat: # routines with specification (Eiffel projects)

0

2000 1500 1000 500 0 150 100

revision

50 0

# routines # routines

1000 800 600 400 200 0 60000 40000

# routines # routines

20000 0

94

pre or post

pre post0

100

200

400 revision

300

500

600

200

revision

400

600

800

GoboXML: Routines with some specification

pre or post

pre post0

GoboKernel: Routines with some specification

# routines

# routines

5000

4000

pre or post

pre post0

400 revision

600

800

100 revision

200

300

Quickgraph: Routines with some specification

pre 200 post pre or post

Boogie: Routines with some specification 12 10 8 6

40 revision

60

80

50 revision

100

150

100

pre or post

pre 0 post

150

250

revision

200

300

350

10

20

revision

30

40

50

shweet: Routines with some specification

pre 100 post pre or post

Dafny: Routines with some specification

Fig. 72. Flat: # routines with specification (C# projects)

pre or post

pre post0

20

Rxx: Routines with some specification

pre or post

pre post0

CCI: Routines with some specification 600 500 400 300

3000

2000

1000

0

250

200

150

100

50

0

# routines # routines

4 2 0 2000 1500 1000 500 0

# routines # routines

60

400

400 300 200 100

200 100 0 10 8 6 4 2 0

95

# routines

pre or post

pre 0 post

10

20 revision

30

40

Labs: Routines with some specification

50

# routines # routines

pre or post

pre 0 post

100

200 revision

300

5

10 revision

15

20

25

30

400

pre or post

pre 0 post

200 revision

400

600

800

5

10

revision

15

20

25

RCC: Routines with some specification

pre or post

pre 0 post

ESCJava: Routines with some specification

30

1000 pre or post

pre post0

200 revision

300

50 revision

100

Umbra: Routines with some specification

100

JavaFE: Routines with some specification

pre or post

pre post0

Fig. 73. Flat: # routines with specification (Java projects)

Logging: Routines with some specification

pre or post

pre 0 post

DirectVCGen: Routines with some specification 2500 2000

150 100 50 0 80 60 40 20

# routines # routines

1500 1000 500 0 600 500 400 300 200 100 0

# routines # routines

800 600 400 200 30 20 10 0

96

150

400

% routines or classes

% routines or classes

50

100 revision

150

200

250

300

inv

pre post0 50

100 revision

150

200

250

200

400

800

revision

600

1000

1200

inv

pre post0 20

40 revision

60

80

100

120

GoboTime: % routines and classes with specification

inv

pre post0

EiffelBase: % routines and classes with specification

50

revision

100

150

200

inv

pre post0

50

revision

100

150

200

GoboUtility: % routines and classes with specification

inv

pre post0

EiffelProgramAnalysis: % routines and classes with specification

0.15

Fig. 74. Flat: % routines and classes with specification (Eiffel projects)

GoboStructure: % routines and classes with specification

inv

pre post0

AutoTest: % routines and classes with specification 0.7 0.6

1.0 0.8 0.6

0.60

0.55

0.50

0.45

0.40

0.8

0.7

0.6

0.5

% routines or classes % routines or classes

0.5 0.4 0.3 0.6 0.4 0.2 0.0

% routines or classes % routines or classes

0.10 0.05 0.00 0.8 0.6 0.4 0.2 0.0

% routines or classes % routines or classes

0.4 0.2 0.0 0.8 0.6 0.4 0.2 0.0

97

100

200

400 revision

300

500

600

inv

pre post0

200

revision

400

600

800

GoboXML: % routines and classes with specification

inv

pre post0

GoboKernel: % routines and classes with specification

0.7

0.6

0.5

0.4

0.3

0.2

0.1

% routines or classes

% routines or classes

0.20

0.15

0.10

200

400 revision

600

800

pre post0 100

200

300

Quickgraph: % routines and classes with specification

pre post inv

Boogie: % routines and classes with specification

inv revision

inv

pre post0

inv

pre post0 40 revision

60

80

100

50 revision

100

150

Rxx: % routines and classes with specification

20

CCI: % routines and classes with specification

pre 0 post inv

100

150

250

revision

200

300

350

400

10

20

revision

30

40

50

60

shweet: % routines and classes with specification

pre post inv

Dafny: % routines and classes with specification

Fig. 75. Flat: % routines and classes with specification (C# projects)

0.05

0.00

0.5 0.4 0.3

0.05 0.04 0.03 0.02 0.01 0.00 0.8 0.6 0.4

% routines or classes % routines or classes 0.2 0.0

% routines or classes % routines or classes

0.40 0.35 0.30 0.25 0.20 0.15

0.2 0.1 0.0 0.4 0.3 0.2 0.1 0.0

98

% routines or classes

inv

pre 0 post

10

20 revision

30

40

50

Labs: % routines and classes with specification

0.15

100

200 revision

300

400

inv

pre 0 post 5

10 revision

15

20

30

0.7 inv

pre 0 post

inv

pre 0 post revision

400

600

800

5

10

revision

15

20

25

30

RCC: % routines and classes with specification

200

ESCJava: % routines and classes with specification

inv

100

200 revision

300

400

50 revision

100

150

Umbra: % routines and classes with specification

pre post0

inv

pre post0

JavaFE: % routines and classes with specification

Fig. 76. Flat: % routines and classes with specification (Java projects)

25

Logging: % routines and classes with specification

inv

pre 0 post

DirectVCGen: % routines and classes with specification

0.6 0.5

0.6 0.5 0.4 0.3

0.10 0.05 0.00

% routines or classes % routines or classes

0.35 0.30 0.25 0.20 0.15 0.10 0.05

% routines or classes % routines or classes

0.2 0.1 0.6 0.5 0.4 0.3 0.2 0.1 0.0

% routines or classes % routines or classes

0.4 0.3 0.2 0.1 0.08 0.06 0.04 0.02 0.00

99

# routines or classes

# routines or classes

50

100 revision

150

200

250

300

inv

pre post0 50

100 revision

150

200

250

200

400

800

revision

600

1000

1200

inv

pre post0 20

40 revision

60

80

100

120

GoboTime: Routines and classes with specification

inv

pre post0

EiffelBase: Routines and classes with specification

50

revision

100

150

200

inv

pre post0

50

revision

100

150

200

GoboUtility: Routines and classes with specification

inv

pre post0

800 600

EiffelProgramAnalysis: Routines and classes with specification 1500

Fig. 77. Flat: # routines and classes with specification (Eiffel projects)

GoboStructure: Routines and classes with specification

inv

pre post0

AutoTest: Routines and classes with specification

3000 2000

1000

800

600

400

200

1500

1000

500

0

# routines or classes # routines or classes

1000 500 0 400 300 200 100 0

# routines or classes # routines or classes

1000 500 0 150 100 50 0

# routines or classes # routines or classes

400 200 0 50000 30000 10000 0

100

100

200

400 revision

300

500

600

inv

pre post0

200

revision

400

600

800

GoboXML: Routines and classes with specification

inv

pre post0

GoboKernel: Routines and classes with specification

4000

3000

2000

1000

0

# routines or classes

# routines or classes

250

200

150

100

50

0

200

400 revision

600

800

inv

pre post0 100 revision

200

300

Quickgraph: Routines and classes with specification

pre post inv

Boogie: Routines and classes with specification 12 10 8 6 4 2 0 2000 1500 1000 pre post0

inv

pre post0 40 revision

60

80

50 revision

100

150

100

Rxx: Routines and classes with specification

20

CCI: Routines and classes with specification

pre 0 post inv

100

150

250

revision

200

300

350

400

10

20

revision

30

40

50

60

shweet: Routines and classes with specification

pre post inv

Dafny: Routines and classes with specification

Fig. 78. Flat: # routines and classes with specification (C# projects)

inv

500 0

# routines or classes # routines or classes

500 400 300

350 300 250 200 150 100 50

200 100 0 8 6 4

# routines or classes # routines or classes 2 0

101

# routines or classes

inv

pre 0 post

10

20 revision

30

40

50

Labs: Routines and classes with specification

# routines or classes

150 100 50 0 60 50 40 30 20

100

200 revision

300

400

5

10

15

20

25

30

Logging: Routines and classes with specification

pre 0 post

inv

pre 0 post

DirectVCGen: Routines and classes with specification

pre 0 post

inv

pre 0 post revision

400

600

800

5

10

15

20

25

30

RCC: Routines and classes with specification

200

ESCJava: Routines and classes with specification

inv revision

revision

inv

100

200 revision

300

400

50 revision

100

150

Umbra: Routines and classes with specification

pre post0

inv

pre post0

JavaFE: Routines and classes with specification

Fig. 79. Flat: # routines and classes with specification (Java projects)

inv

10 0

# routines or classes

2500 2000 1500 1000 500 0 600 500 400 300

# routines or classes # routines or classes 100 0

200

1000 800 600 400 200 25 20 15 10

# routines or classes # routines or classes

5 0

102

2.0

50

100 revision

150

200

250

300

inv

pre post0 50

100 revision

150

200

250

8 6

200

400

800

revision

600

1000

1200

inv

pre post0 20

40 revision

60

80

100

120

GoboTime: Specification clauses per routine or class

inv

pre post0

EiffelBase: Specification clauses per routine or class

50

revision

100

150

200

inv

pre post0

50

revision

100

150

200

GoboUtility: Specification clauses per routine or class

inv

pre post0

EiffelProgramAnalysis: Specification clauses per routine or class

Fig. 80. Flat: Specification clauses per routine or class (Eiffel projects)

GoboStructure: Specification clauses per routine or class

inv

pre post0

AutoTest: Specification clauses per routine or class

0.20 0.15 0.10

1.4 1.2 1.0 0.8 0.6 0.4

1.5

1.0

0.5

# clauses per routine or class

# clauses per routine or class

7

6

5

4

3

2

1

# clauses per routine or class # clauses per routine or class

4 2 2.0 1.5 1.0 0.5 0.0

# clauses per routine or class # clauses per routine or class

0.05 0.00 1.5 1.0 0.5 0.0

# clauses per routine or class # clauses per routine or class

0.2 0.0 7 6 5 4 3 2 1 0

103

100

200

400 revision

300

500

600

inv

pre post0

200

revision

400

600

800

GoboXML: Specification clauses per routine or class

inv

pre post0

GoboKernel: Specification clauses per routine or class

3.0

2.5

200

400 revision

600

800

inv

pre post0 100 revision

200

300

Quickgraph: Specification clauses per routine or class

pre post inv

Boogie: Specification clauses per routine or class 0.06 0.05 0.04 0.03

2.0

1.5

1.0

0.5

# clauses per routine or class

# clauses per routine or class

0.0

0.3

0.2

0.1

0.0

# clauses per routine or class

inv

pre post0

inv

pre post0 40 revision

60

80

100

50 revision

100

150

Rxx: Specification clauses per routine or class

20

CCI: Specification clauses per routine or class

1.5 pre 0 post inv

100

150

250

revision

200

300

350

400

10

20

revision

30

40

50

60

shweet: Specification clauses per routine or class

pre post inv

Dafny: Specification clauses per routine or class

Fig. 81. Flat: Specification clauses per routine or class (C# projects)

# clauses per routine or class

0.02 0.01 0.00 2.0 1.5 1.0 0.5 0.0

# clauses per routine or class # clauses per routine or class

1.4 1.2 1.0 0.8 0.6 0.4 0.2

1.0 0.5 0.0 0.6 0.5 0.4 0.3 0.2 0.1 0.0

104

# clauses per routine or class

inv

pre 0 post

10

20 revision

30

40

50

Labs: Specification clauses per routine or class

100

200 revision

300

400

inv

pre 0 post 5

10 revision

15

20

30 inv

pre 0 post

inv

pre 0 post revision

400

600

800

5

10

revision

15

20

25

30

RCC: Specification clauses per routine or class

200

ESCJava: Specification clauses per routine or class

inv

100

200 revision

300

400

50 revision

100

150

Umbra: Specification clauses per routine or class

pre post0

inv

pre post0

JavaFE: Specification clauses per routine or class

Fig. 82. Flat: Specification clauses per routine or class (Java projects)

25

Logging: Specification clauses per routine or class

inv

pre 0 post

DirectVCGen: Specification clauses per routine or class

0.15

1.0 0.8 0.6

3.0 2.5 2.0 1.5

0.10 0.05 0.00

# clauses per routine or class # clauses per routine or class

0.6 0.5 0.4 0.3 0.2 0.1

# clauses per routine or class # clauses per routine or class

0.4 0.2 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0

# clauses per routine or class # clauses per routine or class

1.0 0.5 0.5 0.4 0.3 0.2 0.1 0.0

105

inv

pre post0 50

100 revision

150

200

250

300

# clauses per routine or class

inv

pre post0 200

400

800

revision

600

1000

1200 inv

pre post0 50

revision

100

150

200

inv

pre post0

100

200

400 revision

300

500

600

EiffelBase: Average specification strength per routine or class EiffelProgramAnalysis: Average specification strength per routine or GoboKernel: class Average specification strength per routine or class

# clauses per routine or class

AutoTest: Average specification strength per routine or class

# clauses per routine or class

inv

pre post0 50

100 revision

150

200

# clauses per routine or class

8

7

6

5

4

3

2

5 4 3 2 1 0 inv

pre post0 20

40 revision

60

80

100

120

3.0 2.5 2.0 1.5 1.0 0.5 0.0

# clauses per routine or class

# clauses per routine or class

inv

pre post0

50

revision

100

150

Fig. 83. Flat: Average specification strength per routine or class (Eiffel projects)

250

200

# clauses per routine or class

inv

pre post0

200

revision

400

600

800

GoboStructure: Average specification strength per routine or classGoboTime: Average specification strength per routine or class GoboUtility: Average specification strength per routine or class GoboXML: Average specification strength per routine or class

# clauses per routine or class

3.5

3.0

2.5

2.0

1.5

12 10 8 6 4 2

1.5 1.0 0.5 0.0

3.0 2.5 2.0 1.5 1.0 0.5 0.0 8 6 4 2 0

106

# clauses per routine or class

5

200

400 revision

600

800

inv

pre post0 100 revision

200

300

Quickgraph: Average specification strength per routine or class

pre post inv

Boogie: Average specification strength per routine or class

20

40 revision

60

80

100

50 revision

100

150

100

150

250

revision

200

300

350

400

inv

pre 0 post

10

20

revision

30

40

50

60

shweet: Average specification strength per routine or class

pre post inv

Dafny: Average specification strength per routine or class

Fig. 84. Flat: Average specification strength per routine or class (C# projects)

inv

pre post0

Rxx: Average specification strength per routine or class

inv

pre post0

CCI: Average specification strength per routine or class 4 3 2

2.0 1.5 1.0 0.5

4

3

2

1

2.0

1.5

1.0

0.5

0.0

# clauses per routine or class

# clauses per routine or class # clauses per routine or class

0.0 8 6 4 2 0

# clauses per routine or class # clauses per routine or class

inv

pre 0 post

10

20 revision

30

40

50

Labs: Average specification strength per routine or class

3.0 2.5 2.0 1.5 1.0

1 0 2.0 1.5 1.0 0.5 0.0

107

# clauses per routine or class

100

200 revision

300

400

inv

pre 0 post 5

10 revision

15

25

30

200 revision

400

600

800

inv

pre 0 post 5

10

revision

15

20

25

30

RCC: Average specification strength per routine or class

inv

pre 0 post

100

200 revision

300

400

inv

pre post0

50 revision

100

150

Umbra: Average specification strength per routine or class

inv

pre post0

JavaFE: Average specification strength per routine or class

Fig. 85. Flat: Average specification strength per routine or class (Java projects)

20

Logging: Average specification strength per routine or class

inv

pre 0 post

DirectVCGen: Average specification strength per routine or class ESCJava: Average specification strength per routine or class

# clauses per routine or class

2.0 1.5 1.0 0.5 0.0 2.0

6 5 4

5 4 3 2

1.8 1.6 1.4 1.2 1.0

# clauses per routine or class

# clauses per routine or class # clauses per routine or class

1 6 5 4 3 2 1

# clauses per routine or class # clauses per routine or class

3 2 6 5 4 3 2 1 0

108

# routines

# routines

100

150 revision

200

250

300

inv strong

pre weak pre strong post weak post strong 0 inv weak 50

100 revision

150

200

250

GoboStructure: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong 0 50 inv weak

AutoTest: Weakening and strengthening 200 150

400

800

revision

600

1000

1200

40

60 revision

80

100

120

50

100 revision

150

200

inv strong

pre weak pre strong post weak post strong 0 inv weak

50

revision

100

150

200

GoboUtility: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong 0 inv weak

EiffelProgramAnalysis: Weakening and strengthening

Fig. 86. Flat: Weakening and strengthening (Eiffel projects)

pre weak pre strong post weak post strong 20 inv 0 weak inv strong

GoboTime: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong 0 200 inv weak

EiffelBase: Weakening and strengthening 70 60 50 40

30 25 20

20

15

10

5

0

120

100

80

60

40

20

0

# routines # routines

100 50 0 14 12 10 8 6 4 2 0

# routines # routines

30 20 10 0 8 6 4 2 0

# routines # routines

15 10 5 0 1500 1000 500 0

109

200

400 revision

300

500

600

inv strong

pre weak pre strong post weak post strong 0 inv weak

200

revision

400

600

800

GoboXML: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong 0 100 inv weak

GoboKernel: Weakening and strengthening

# routines

# routines

400 revision

600

800

inv strong

pre weak pre strong post weak post strong 0 inv weak 100 revision

200

300

Quickgraph: Weakening and strengthening

inv strong

pre weak pre strong post weak post strong inv weak 200

Boogie: Weakening and strengthening

40 revision

60

80

50 revision

100

Rxx: Weakening and strengthening

20

150

100

150

250

revision

200

300

350

20

revision

30

40

50

shweet: Weakening and strengthening

pre weak pre strong post weak post strong 10 inv0weak inv strong

inv strong

pre weak pre strong post weak post strong inv weak 100

Dafny: Weakening and strengthening

Fig. 87. Flat: Weakening and strengthening (C# projects)

pre weak pre strong post weak post strong inv 0 weak inv strong

pre weak pre strong post weak post strong inv 0weak inv strong

CCI: Weakening and strengthening

20 15

3.0 2.5 2.0 1.5

250

200

150

100

50

0

80

60

40

20

0

# routines # routines

1.0 0.5 0.0 15 10 5 0

# routines # routines

60

400

150 100 50 0

10 5 0 2.0 1.5 1.0 0.5 0.0

110

# routines

pre weak pre strong post weak post strong inv0weak inv strong

10

20 revision

30

40

Labs: Weakening and strengthening

50

# routines # routines

100

200 revision

300

pre weak pre strong post weak post strong 5 inv0 weak inv strong 10 revision

15

20

25

30

400

200 revision

400

600

800

10

revision

15

20

25

RCC: Weakening and strengthening

pre weak pre strong post weak post strong inv0 weak 5 inv strong

pre weak pre strong post weak post strong inv 0weak inv strong

ESCJava: Weakening and strengthening

30

200 revision

300

50 revision

100

Umbra: Weakening and strengthening

pre weak pre strong post weak post strong inv 0 weak inv strong

inv strong

100

JavaFE: Weakening and strengthening

pre weak pre strong post weak post strong 0 inv weak

Fig. 88. Flat: Weakening and strengthening (Java projects)

Logging: Weakening and strengthening

pre weak pre strong post weak post strong inv0 weak inv strong

DirectVCGen: Weakening and strengthening 300 250 200

70 60 50

10 8 6 4 2 0 20 15 10 5 0

# routines # routines

150 100 50 0 600 500 400 300 200 100 0

# routines # routines

40 30 20 10 0 20 15 10 5 0

111

150

400

% routines

% routines

0.80

0.75

0.70

0.65

0.60

0.55

0.9

0.8

0.7

0.6

0.5

0.4

100

150 revision

200

250

300

0 public non−public

50

100 revision

150

200

400

800

revision

600

1000

1200

0 20 public non−public

40

60

80

100

GoboTime: % routines with pre or post

0 200 public non−public

EiffelBase: % routines with pre or post

revision

120

50

100 revision

150

0 public non−public

50

revision

100

150

200

200

GoboUtility: % routines with pre or post

0 public non−public

EiffelProgramAnalysis: % routines with pre or post

Fig. 89. Flat: % routines with specification: public vs nonpublic (Eiffel projects)

250

GoboStructure: % routines with pre or post

0 50 public non−public

AutoTest: % routines with pre or post 0.7 0.6 0.5 0.4 0.3 1.0 0.8 0.6 0.2

% routines % routines

0.5 0.4

0.0

0.4

% routines % routines

0.3 0.2 0.1 0.0 1.0 0.8 0.6 0.4 0.2 0.0

% routines % routines

1.0 0.8 0.6 0.4 0.2 0.0 0.6 0.4 0.2 0.0

112

200

400 revision

300

500

600

0 public non−public

200

revision

400

600

800

GoboXML: % routines with pre or post

0 100 public non−public

GoboKernel: % routines with pre or post

% routines

% routines

0.80

0.75

0.70

0.65

0.60

0.55

0.50

0.20

0.15

400 revision

600

800

0 public non−public

100

200

300

Quickgraph: % routines with pre or post

200 public non−public

Boogie: % routines with pre or post

revision

0 public non−public

0 public non−public

40 revision

60

80

50 revision

100

Rxx: % routines with pre or post

20

CCI: % routines with pre or post

150

100

150

250

revision

200

300

350

0 10 public non−public

20

revision

30

40

50

shweet: % routines with pre or post

public 100 non−public

Dafny: % routines with pre or post

Fig. 90. Flat: % routines with specification: public vs nonpublic (C# projects)

0.05

0.7 0.6 0.5 0.4

0.15

0.00

0.10

% routines % routines

0.10 0.05 0.00 1.0 0.8 0.6 0.4 0.2 0.0

% routines % routines

60

400

0.60 0.55 0.50 0.45 0.40 0.35 0.30

0.3 0.2 0.4 0.3 0.2 0.1 0.0

113

% routines

0 public non−public

10

20 revision

30

40

Labs: % routines with pre or post

50

% routines % routines

100

200 revision

300

10 revision

15

25

30

400

0 5 public non−public

0 public non−public revision

400

600

10

revision

15

20

25

RCC: % routines with pre or post

200

800

ESCJava: % routines with pre or post

30

0.7 0 public non−public

0 public non−public

200 revision

300

50 revision

100

Umbra: % routines with pre or post

100

JavaFE: % routines with pre or post

Fig. 91. Flat: % routines with specification: public vs nonpublic (Java projects)

20

Logging: % routines with pre or post

0 5 public non−public

0 public non−public

DirectVCGen: % routines with pre or post 0.7 0.6 0.5

0.20 0.15 0.10 0.05 0.00 0.5 0.4 0.3 0.2 0.1

% routines % routines

0.4 0.3 0.2 0.7 0.6 0.5 0.4 0.3 0.2 0.1

% routines % routines

0.6 0.5 0.4 0.25 0.20 0.15 0.10 0.05 0.00

114

150

400

25

15

10

5

0

# classes

−A weak

+A same +A strong +A weak −A same 0 −A strong 50

100

150 revision

200

250

300 −A weak

+A same +A strong +A weak −A same 0 200 −A strong 400

800

revision

600

1000

1200

−A weak

+A same +A strong +A weak −A same 0 −A strong 50

100

150 revision

200

250

20

40

60 revision

80

100

120

100 revision

−A weak

+A same +A strong +A weak −A same 0 −A strong

50

revision

100

Fig. 92. Flat: Weakening and strengthening of class invariants (Eiffel projects)

+A same +A strong +A weak −A same −A 0 strong −A weak

50

150

200

150

200

GoboUtility: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same 0 −A strong

200

400 revision

300

500

600

−A weak

+A same +A strong +A weak −A same 0 −A strong

200

revision

400

600

800

GoboXML: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same 0 100 −A strong

EiffelBase: Weakening and strengthening of class invariants EiffelProgramAnalysis: Weakening and strengthening of class invariants GoboKernel: Weakening and strengthening of class invariants 80

AutoTest: Weakening and strengthening of class invariants

# classes # classes

GoboStructure: Weakening and strengthening of class invariants GoboTime: Weakening and strengthening of class invariants

# classes

20

15

10

5

0

25 20 15 10 5 0 3.0 2.5 2.0 1.5 1.0 0.5 0.0

2.0 1.5 1.0 0.5

60 40 20 0 1.0 0.8 0.6 0.4 0.2 0.0

# classes # classes

# classes # classes

0.0 250 200 150 100 50 0

115

# classes

400 revision

600

800

−A weak

+A same +A strong +A weak −A same 0 −A strong 100 revision

200

300

Quickgraph: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same −A strong200

Boogie: Weakening and strengthening of class invariants

1.0

0.5

20

40 revision

60

80

100

1.0

50 revision

100

150

150

250

revision

200

300

350

400

+A same +A strong +A weak −A same −A0strong −A weak

10

20

revision

30

40

50

60

shweet: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same −A strong100

Dafny: Weakening and strengthening of class invariants

Fig. 93. Flat: Weakening and strengthening of class invariants (C# projects)

+A same +A strong +A weak −A same −A 0 strong −A weak

Rxx: Weakening and strengthening of class invariants

+A same +A strong +A weak −A same −A 0strong −A weak

CCI: Weakening and strengthening of class invariants 1.0 0.5 0.0

0.5 0.0 −0.5

0.0

−0.5

−1.0

1.0

0.5

0.0

−0.5

−1.0

# classes

# classes # classes

−1.0 1.0 0.5 0.0 −0.5 −1.0

# classes # classes

1.0 0.5 0.0 −0.5 −1.0

−0.5 −1.0 1.0 0.5 0.0 −0.5 −1.0

116

# classes

+A same +A strong +A weak −A same −A0strong −A weak

10

20 revision

30

40

50

Labs: Weakening and strengthening of class invariants

# classes # classes

100

200 revision

300

400

+A same +A strong +A weak −A same −A0 strong −A weak 5

10 revision

15

25

30

200 revision

400

600

800

+A same +A strong +A weak −A same −A0 strong −A weak 5

10

revision

15

20

25

30

RCC: Weakening and strengthening of class invariants

+A same +A strong +A weak −A same −A 0strong −A weak

ESCJava: Weakening and strengthening of class invariants

100

200 revision

300

400

−A weak

+A same +A strong +A weak −A same 0 −A strong

50 revision

100

150

Umbra: Weakening and strengthening of class invariants

−A weak

+A same +A strong +A weak −A same 0 −A strong

JavaFE: Weakening and strengthening of class invariants

Fig. 94. Flat: Weakening and strengthening of class invariants (Java projects)

20

Logging: Weakening and strengthening of class invariants

+A same +A strong +A weak −A same −A0 strong −A weak

DirectVCGen: Weakening and strengthening of class invariants 1.0 0.5

1.0 0.5

1.0 0.5 0.0 −0.5 −1.0 1.0 0.5 0.0 −0.5 −1.0

# classes # classes

0.0 −0.5 −1.0 1.0 0.5 0.0 −0.5 −1.0

# classes # classes

0.0 −0.5 −1.0 1.0 0.5 0.0 −0.5 −1.0

117

13

Data About the Control Group

The following tables report the same measures as those used in the main analysis, but target 10 student projects discussed at the end of Section 6.

118

# CLASSES % CLASSES INV # ROUTINES % ROUTINES SPEC % ROUTINES PRE % ROUTINES POST AVG ROUTINES PRE AVG ROUTINES POST Project m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m dose 76 0 16 28 6 0 0.53 1 0.12 0 34 86 26 0 0.36 1 0.18 0 0.29 1 0.15 0 0.23 1 0.18 0 1.46 2.12 0.23 0 2 3 0.57 0 dose 77 0 24 25 6 0 0.83 0.88 0.17 0 150 193 57 0 0.73 0.88 0.14 0 0.26 0.36 0.1 0 0.61 0.88 0.15 0 1.52 1.71 0.45 0 4.07 5.2 1.36 0 dose 78 0 33 35 8 0 0.37 0.41 0.08 0 93 96 25 0 0.12 0.16 0.02 0 0.06 0.12 0.02 0 0.1 0.12 0.04 0 1.67 1.8 0.32 0 1.22 1.56 0.51 0 dose 80 0 9 9 1 0 0.25 0.44 0.06 0 35 43 12 0 0.39 0.83 0.13 0 0.21 0.83 0.18 0 0.28 0.58 0.08 0 1.5 1.5 0.25 0 1.5 1.69 0.23 0 dose 86 0 37 79 22 0 0.28 1 0.19 0 172 406 107 0 0.49 0.68 0.15 0 0.41 0.56 0.12 0 0.24 0.3 0.08 0 1.4 1.64 0.19 0 1.55 2.44 0.44 0 dose 87 0 14 18 4 0 0.2 0.67 0.11 0 134 163 46 0 0.49 0.84 0.17 0 0.37 0.59 0.1 0 0.22 0.59 0.13 0 1.44 1.72 0.34 0 1.81 2.17 0.53 0 dose 88 0 26 32 4 0 0.74 0.85 0.14 0 229 371 87 0 0.66 0.75 0.15 0 0.59 0.71 0.19 0 0.51 0.68 0.14 0 1.66 1.88 0.48 0 1.6 1.84 0.31 0 dose 89 0 16 16 2 0 0.44 0.9 0.14 0 89 132 39 0 0.36 0.48 0.1 0 0.34 0.44 0.09 0 0.22 0.44 0.09 0 1.16 1.83 0.32 0 1.42 1.6 0.34 0 dose 90 3 12 16 3 0 0.27 0.62 0.1 0 51 131 40 0 0.38 1 0.14 0 0.18 1 0.12 0 0.32 1 0.13 0 1.22 1.44 0.29 0 1.06 1.2 0.27 0 dose 92 19 59 61 4 0 0.05 0.07 0.01 24 456 562 122 0.27 0.31 0.92 0.11 0.17 0.22 0.39 0.02 0.11 0.12 0.78 0.1 1 1.17 1.37 0.04 1 1.02 1.03 0 0

Table 95. Specification overall statistics with non-flattened classes.

M 3.12 2.46 1.92 5 3 2 2.2 1.14 1.8 3

AVG INV

µ 2.88 1.81 1.92 1.67 1.57 1 1.94 1.14 1 3

σ 0.61 0.41 0.4 1.37 0.44 0.47 0.37 0.08 0.15 0.3

119

120

Table 96. Specification overall statistics with flattened classes.

# CLASSES % CLASSES INV # ROUTINES % ROUTINES SPEC % ROUTINES PRE % ROUTINES POST AVG ROUTINES PRE AVG ROUTINES POST AVG INV Project m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ dose 76 0 16 28 6 0 0.79 1 0.14 0 46 122 37 0 0.39 1 0.13 0 0.33 1 0.11 0 0.2 1 0.16 0 1.29 1.91 0.21 0 1.71 2.5 0.46 0 2.33 2.67 0.45 dose 77 0 24 25 6 0 0.88 0.93 0.16 0 184 228 65 0 0.69 0.91 0.15 0 0.25 0.34 0.1 0 0.57 0.91 0.17 0 1.42 1.62 0.42 0 3.71 4.78 1.27 0 2 2.58 0.43 dose 78 0 33 35 8 0 0.69 0.72 0.2 0 156 162 43 0 0.31 0.34 0.09 0 0.25 0.27 0.07 0 0.26 0.28 0.11 0 2 2.1 0.47 0 1.41 1.5 0.55 0 2.52 2.54 0.63 dose 80 0 9 9 1 0 0.25 0.44 0.06 0 35 44 12 0 0.38 0.83 0.13 0 0.21 0.83 0.18 0 0.28 0.58 0.08 0 1.5 1.5 0.25 0 1.5 1.69 0.23 0 1.67 5 1.37 dose 86 0 37 79 22 0 0.56 1 0.19 0 206 574 169 0 0.49 0.6 0.11 0 0.31 0.51 0.1 0 0.29 0.35 0.1 0 1.44 1.7 0.2 0 1.32 2.44 0.47 0 1.46 3 0.44 dose 87 0 14 18 4 0 0.2 0.67 0.11 0 134 163 46 0 0.49 0.84 0.17 0 0.37 0.59 0.1 0 0.22 0.59 0.13 0 1.44 1.72 0.34 0 1.81 2.17 0.53 0 1.33 2 0.47 dose 88 0 26 32 4 0 0.78 0.9 0.15 0 310 449 106 0 0.67 0.73 0.15 0 0.57 0.64 0.17 0 0.55 0.73 0.14 0 1.64 1.87 0.48 0 1.53 1.77 0.29 0 3.43 3.63 0.68 dose 89 0 16 16 2 0 0.5 0.92 0.15 0 89 132 39 0 0.53 0.84 0.14 0 0.5 0.81 0.14 0 0.26 0.56 0.11 0 1.39 1.79 0.25 0 1.33 1.42 0.21 0 1.12 1.12 0.08 dose 90 3 12 16 3 0 0.27 0.62 0.1 0 89 196 59 0 0.46 1 0.18 0 0.29 1 0.13 0 0.36 1 0.14 0 1.08 1.33 0.24 0 1.24 1.41 0.31 0 1 3 0.33 dose 92 19 59 61 4 0 0.1 0.14 0.02 56 862 1029 206 0.42 0.48 0.96 0.12 0.08 0.27 0.39 0.05 0.2 0.22 0.86 0.11 1 1.36 1.41 0.07 1 1 1.06 0.01 0 3 3 0.3

Project dose 76 dose 77 dose 78 dose 80 dose 86 dose 87 dose 88 dose 89 dose 90 dose 92

lang Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel

LOC # CLASSES % CLASSES INV # ROUTINES % ROUTINES SPEC % ROUTINES PRE % ROUTINES POST rev age m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ 151 8 0 2051 3494 1055 0 16 28 6 0 0.53 1 0.12 0 34 86 26 0 0.36 1 0.18 0 0.29 1 0.15 0 0.23 1 0.18 70 8 0 3486 4349 1177 0 24 25 6 0 0.83 0.88 0.17 0 150 193 57 0 0.73 0.88 0.14 0 0.26 0.36 0.1 0 0.61 0.88 0.15 73 8 0 2908 3208 930 0 33 35 8 0 0.37 0.41 0.08 0 93 96 25 0 0.12 0.16 0.02 0 0.06 0.12 0.02 0 0.1 0.12 0.04 143 7 0 1556 1944 516 0 9 9 1 0 0.25 0.44 0.06 0 35 43 12 0 0.39 0.83 0.13 0 0.21 0.83 0.18 0 0.28 0.58 0.08 170 8 0 3086 8827 2519 0 37 79 22 0 0.28 1 0.19 0 172 406 107 0 0.49 0.68 0.15 0 0.41 0.56 0.12 0 0.24 0.3 0.08 235 7 0 2358 4460 1287 0 14 18 4 0 0.2 0.67 0.11 0 134 163 46 0 0.49 0.84 0.17 0 0.37 0.59 0.1 0 0.22 0.59 0.13 113 8 0 4320 8786 2350 0 26 32 4 0 0.74 0.85 0.14 0 229 371 87 0 0.66 0.75 0.15 0 0.59 0.71 0.19 0 0.51 0.68 0.14 216 6 0 4370 7290 2093 0 16 16 2 0 0.44 0.9 0.14 0 89 132 39 0 0.36 0.48 0.1 0 0.34 0.44 0.09 0 0.22 0.44 0.09 155 7 30 833 2764 752 3 12 16 3 0 0.27 0.62 0.1 0 51 131 40 0 0.38 1 0.14 0 0.18 1 0.12 0 0.32 1 0.13 292 6 522 11374 16372 4243 19 59 61 4 0 0.05 0.07 0.01 24 456 562 122 0.27 0.31 0.92 0.11 0.17 0.22 0.39 0.02 0.11 0.12 0.78 0.1

Table 97. Project specification statistics for non-flattened classes.

121

122

Project dose 76 dose 77 dose 78 dose 80 dose 86 dose 87 dose 88 dose 89 dose 90 dose 92

lang Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel Eiffel

LOC rev age m µ M 151 8 0 2051 3494 70 8 0 3486 4349 73 8 0 2908 3208 143 7 0 1556 1944 170 8 0 3086 8827 235 7 0 2358 4460 113 8 0 4320 8786 216 6 0 4370 7290 155 7 30 833 2764 292 6 522 11374 16372

Table 98. Project specification statistics for flattened classes.

# CLASSES % CLASSES INV # ROUTINES % ROUTINES SPEC % ROUTINES PRE % ROUTINES POST σ m µM σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ 1055 0 16 28 6 0 0.79 1 0.14 0 46 122 37 0 0.39 1 0.13 0 0.33 1 0.11 0 0.2 1 0.16 1177 0 24 25 6 0 0.88 0.93 0.16 0 184 228 65 0 0.69 0.91 0.15 0 0.25 0.34 0.1 0 0.57 0.91 0.17 930 0 33 35 8 0 0.69 0.72 0.2 0 156 162 43 0 0.31 0.34 0.09 0 0.25 0.27 0.07 0 0.26 0.28 0.11 516 0 9 9 1 0 0.25 0.44 0.06 0 35 44 12 0 0.38 0.83 0.13 0 0.21 0.83 0.18 0 0.28 0.58 0.08 2519 0 37 79 22 0 0.56 1 0.19 0 206 574 169 0 0.49 0.6 0.11 0 0.31 0.51 0.1 0 0.29 0.35 0.1 1287 0 14 18 4 0 0.2 0.67 0.11 0 134 163 46 0 0.49 0.84 0.17 0 0.37 0.59 0.1 0 0.22 0.59 0.13 2350 0 26 32 4 0 0.78 0.9 0.15 0 310 449 106 0 0.67 0.73 0.15 0 0.57 0.64 0.17 0 0.55 0.73 0.14 2093 0 16 16 2 0 0.5 0.92 0.15 0 89 132 39 0 0.53 0.84 0.14 0 0.5 0.81 0.14 0 0.26 0.56 0.11 752 3 12 16 3 0 0.27 0.62 0.1 0 89 196 59 0 0.46 1 0.18 0 0.29 1 0.13 0 0.36 1 0.14 4243 19 59 61 4 0 0.1 0.14 0.02 56 862 1029 206 0.42 0.48 0.96 0.12 0.08 0.27 0.39 0.05 0.2 0.22 0.86 0.11

−A inv weak vs same

−A inv strong vs same

2.50E+00 1.18E-02 -3.00E+00 -9.94E-01 2.50E+00 1.18E-02 -3.00E+00 -9.94E-01

+A inv strong vs same

post weak vs strong

3.50E+00 1.40E-02 -1.00E+00 -4.39E-01 3.50E+00 1.40E-02 -1.00E+00 -4.39E-01

+A inv weak vs same

NE pre weak vs strong

1.00E+00 1.26E-02 -3.50E+00 -7.05E-01 1.00E+00 1.26E-02 -3.50E+00 -7.05E-01

NE inv weak vs strong

pre weak vs strong

3.05E+01 3.74E-01 2.50E+00 3.93E-01 3.05E+01 3.74E-01 2.50E+00 3.93E-01

inv weak vs strong

NE chang vs unch spec

0.00E+00 1.95E-03 -4.10E+01 -1.19E+00 0.00E+00 1.95E-03 -4.10E+01 -1.19E+00

NE post weak vs strong

chang vs unch spec V p ∆(µ) d V p ∆(µ) d

0.00E+00 1.50E+00 4.18E-02 0.00E+00 -2.00E+00 0.00E+00 -7.04E-01 0.00E+00 1.50E+00 4.18E-02 0.00E+00 -2.00E+00 0.00E+00 -7.04E-01

2.00E+00 8.90E-02 -5.00E-01 -4.66E-01 2.00E+00 8.90E-02 -5.00E-01 -4.66E-01

0.00E+00 5.86E-03 -1.50E+01 -1.41E+00 0.00E+00 5.86E-03 -1.50E+01 -1.41E+00

0.00E+00 5.86E-03 -1.40E+01 -1.33E+00 0.00E+00 5.86E-03 -1.40E+01 -1.33E+00

0.00E+00 5.83E-03 -4.50E+00 -1.14E+00 0.00E+00 5.83E-03 -4.50E+00 -1.14E+00

0.00E+00 5.76E-03 -4.50E+00 -1.19E+00 0.00E+00 5.76E-03 -4.50E+00 -1.19E+00

−A inv weak vs same

−A inv strong vs same

0.00E+00 5.89E-03 -8.00E+00 -9.48E-01 0.00E+00 5.89E-03 -8.00E+00 -9.48E-01

+A inv strong vs same

0.00E+00 5.67E-03 -2.00E+00 -5.63E-01 0.00E+00 5.67E-03 -2.00E+00 -5.63E-01

+A inv weak vs same

post weak vs strong

6.00E+00 3.22E-02 -8.00E+00 -7.41E-01 6.00E+00 3.22E-02 -8.00E+00 -7.41E-01

NE inv weak vs strong

NE pre weak vs strong

2.80E+01 5.54E-01 2.50E+00 2.61E-01 2.80E+01 5.54E-01 2.50E+00 2.61E-01

inv weak vs strong

pre weak vs strong

0.00E+00 1.95E-03 -1.31E+02 -9.99E-01 0.00E+00 1.95E-03 -1.31E+02 -9.99E-01

NE post weak vs strong

NE chang vs unch spec

V p ∆(µ) d V p ∆(µ) d

chang vs unch spec

Table 99. Change analysis with majority for non-flattened (top) and flattened (bottom) classes.

0.00E+00 5.00E+00 4.36E-02 0.00E+00 -3.00E+00 0.00E+00 -8.55E-01 0.00E+00 5.00E+00 4.36E-02 0.00E+00 -3.00E+00 0.00E+00 -8.55E-01

2.50E+00 3.32E-02 -1.00E+00 -5.94E-01 2.50E+00 3.32E-02 -1.00E+00 -5.94E-01

0.00E+00 1.95E-03 -2.00E+01 -1.34E+00 0.00E+00 1.95E-03 -2.00E+01 -1.34E+00

0.00E+00 5.89E-03 -1.70E+01 -1.28E+00 0.00E+00 5.89E-03 -1.70E+01 -1.28E+00

0.00E+00 5.86E-03 -7.00E+00 -1.26E+00 0.00E+00 5.86E-03 -7.00E+00 -1.26E+00

0.00E+00 5.86E-03 -8.00E+00 -1.29E+00 0.00E+00 5.86E-03 -8.00E+00 -1.29E+00

Table 100. Change analysis for non-flattened (top) and flattened (bottom) classes.

123

124

Project dose 76 dose 77 dose 78 dose 80 dose 86 dose 87 dose 88 dose 89 dose 90 dose 92 Overall

τ 0.89 0.86 0.48 1.00 0.35 1.00 0.89 1.00 1.00 1.00 0.87

p 0.00E+00 0.00E+00 4.44E-16 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 9.70E-04 0.00E+00

τ 0.76 0.81 0.78 1.00 0.68 1.00 0.89 0.76 0.76 0.14 0.62

p 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 3.15E-10 0.00E+00 0.00E+00

τ 0.95 0.94 0.80 1.00 0.87 1.00 0.83 0.77 0.38 0.41 0.87

p 0.00E+00 0.00E+00 0.00E+00 0.00E+00 3.42E-05 0.00E+00 6.66E-16 0.00E+00 0.00E+00 0.00E+00 0.00E+00

τ 0.66 0.79 0.86 1.00 0.23 0.85 0.60 1.00 1.00 1.00 0.79

CLASSES W / INV AVG PRE STRENGTH AVG POST STRENGTH AVG INV STRENGTH

p 0.00E+00 0.00E+00 7.58E-08 0.00E+00 7.07E-11 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00

%

Table 101. Correlation of measures in flat and non-flat classes.

τ 0.67 0.96 0.53 0.94 0.80 1.00 0.93 0.58 0.71 0.71 0.59

ROUTINES W / SPEC

p 0.00E+00 0.00E+00 1.05E-09 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00 0.00E+00

%

Project dose 76 dose 77 dose 78 dose 80 dose 86 dose 87 dose 88 dose 89 dose 90 dose 92 Overall

% SPEC /# ROUTINES p τ 8.31E-31 -0.66 7.21E-08 -0.45 6.71E-01 -0.04 4.91E-20 -0.57 1.61E-08 -0.30 2.06E-06 -0.21 4.02E-01 0.05 1.40E-14 -0.36 2.08E-09 -0.33 9.80E-67 -0.69 5.76E-06 -0.08

# SPEC /# ROUTINES p τ 0.00E+00 0.65 0.00E+00 0.94 2.82E-04 0.34 0.00E+00 0.56 0.00E+00 0.79 0.00E+00 0.51 0.00E+00 0.75 0.00E+00 0.95 0.00E+00 0.84 0.00E+00 0.92 0.00E+00 0.79

% INV /# CLASSES p τ 8.79E-45 -0.85 1.77E-07 0.49 5.70E-04 0.31 3.38E-04 -0.28 1.67E-15 -0.43 6.42E-24 -0.50 1.19E-02 -0.19 8.79E-40 -0.76 7.74E-26 -0.66 3.89E-44 -0.67 1.76E-27 -0.19

# INV /# CLASSES p τ 0.00E+00 0.89 0.00E+00 0.91 0.00E+00 0.82 9.36E-01 0.01 0.00E+00 0.90 3.93E-05 0.22 0.00E+00 0.74 1.68E-30 -0.68 4.00E-15 0.54 3.91E-03 -0.15 0.00E+00 0.30

AVG /% PRE

p 1.11E-15 5.04E-03 2.90E-10 2.40E-25 0.00E+00 1.93E-02 8.71E-01 0.00E+00 3.69E-01 5.10E-09 0.00E+00

τ 0.47 0.24 -0.61 -0.72 0.65 -0.11 -0.01 0.47 -0.05 -0.24 0.20

AVG /% POST

p 3.20E-09 1.27E-03 1.39E-04 1.30E-04 2.49E-06 1.28E-08 1.32E-01 0.00E+00 0.00E+00 0.00E+00 0.00E+00

τ 0.34 -0.27 0.35 0.24 0.25 -0.26 -0.10 0.59 0.60 0.44 0.41

AVG /% INV

p 9.84E-01 9.03E-09 6.82E-14 9.15E-01 1.72E-13 0.00E+00 1.08E-02 6.02E-59 1.62E-05 2.00E-03 8.95E-03

τ -0.00 0.52 0.71 -0.01 -0.41 0.66 0.19 -0.93 0.31 -0.16 -0.05

Table 102. Correlation of measures of specification in non-flat classes.

Project dose 76 dose 77 dose 78 dose 80 dose 86 dose 87 dose 88 dose 89 dose 90 dose 92 Overall

% SPEC /# ROUTINES p τ 6.87E-15 -0.45 9.81E-08 -0.44 9.22E-07 0.42 7.68E-25 -0.63 6.16E-02 -0.10 2.06E-06 -0.21 8.09E-01 0.02 1.27E-47 -0.68 1.92E-13 -0.41 2.12E-118 -0.92 9.48E-01 0.00

# SPEC /# ROUTINES p τ 0.00E+00 0.84 0.00E+00 0.93 0.00E+00 0.84 0.00E+00 0.54 0.00E+00 0.96 0.00E+00 0.51 0.00E+00 0.76 0.00E+00 0.96 0.00E+00 0.73 0.00E+00 0.73 0.00E+00 0.84

% INV /# CLASSES p τ 9.71E-42 -0.82 3.10E-04 0.34 5.35E-03 0.25 3.38E-04 -0.28 2.04E-05 0.23 6.42E-24 -0.50 5.39E-05 -0.30 2.34E-39 -0.76 7.74E-26 -0.66 3.89E-44 -0.67 2.08E-10 -0.11

# INV /# CLASSES p τ 0.00E+00 0.94 0.00E+00 0.91 0.00E+00 0.94 9.36E-01 0.01 0.00E+00 0.94 3.93E-05 0.22 0.00E+00 0.73 1.39E-28 -0.66 4.00E-15 0.54 3.91E-03 -0.15 0.00E+00 0.44

AVG /% PRE

p 0.00E+00 8.46E-07 1.68E-03 8.74E-25 0.00E+00 1.93E-02 4.96E-01 0.00E+00 2.05E-03 2.16E-12 0.00E+00

Table 103. Correlation of measures of specification in flat classes.

125

τ 0.71 0.41 0.27 -0.70 0.51 -0.11 -0.04 0.62 0.18 0.29 0.23

AVG /% POST

p 5.77E-09 9.37E-04 1.79E-06 5.63E-05 3.84E-04 1.28E-08 6.50E-02 0.00E+00 3.55E-02 0.00E+00 0.00E+00

τ 0.34 -0.28 0.41 0.25 -0.19 -0.26 -0.12 0.41 0.12 0.57 0.23

AVG /% INV

p 3.70E-09 8.18E-09 2.17E-04 9.15E-01 4.42E-02 0.00E+00 1.66E-04 1.16E-58 1.62E-05 2.00E-03 4.81E-01

τ -0.35 0.54 0.34 -0.01 0.11 0.70 0.28 -0.93 0.31 -0.16 -0.01

% PRE PUBLIC / PRIVATE % POST PUBLIC / PRIVATE % SPEC PUBLIC / PRIVATE Project p τ p τ p τ dose 76 0.00E+00 0.51 0.00E+00 0.83 0.00E+00 0.48 dose 77 8.76E-10 0.53 1.93E-14 0.67 5.99E-08 0.47 dose 78 3.01E-12 -0.62 3.85E-03 0.25 2.07E-01 0.11 dose 80 3.86E-01 0.05 2.25E-06 -0.29 3.13E-01 -0.06 dose 86 0.00E+00 0.72 0.00E+00 0.62 0.00E+00 0.69 dose 87 6.68E-02 -0.10 6.69E-01 -0.02 3.17E-01 0.05 dose 88 5.89E-02 0.13 2.09E-10 0.42 8.45E-02 0.12 dose 89 2.39E-04 0.17 0.00E+00 0.45 1.55E-06 0.23 dose 90 1.79E-01 0.09 1.11E-01 -0.10 5.93E-01 -0.03 dose 92 4.66E-15 0.33 3.62E-03 -0.12 2.75E-01 0.05 Overall 0.00E+00 0.23 0.00E+00 0.21 0.00E+00 0.16 Table 104. Correlation of measures between public and private routines in non-flat classes.

% PRE PUBLIC / PRIVATE % POST PUBLIC / PRIVATE % SPEC PUBLIC / PRIVATE Project p τ p τ p τ dose 76 7.26E-01 -0.02 0.00E+00 0.79 2.30E-09 0.34 dose 77 1.11E-13 0.64 4.22E-15 0.68 1.76E-10 0.55 dose 78 1.84E-01 0.11 4.17E-03 0.25 2.43E-01 0.10 dose 80 2.09E-01 0.08 6.54E-05 -0.24 8.02E-01 0.02 dose 86 0.00E+00 0.64 0.00E+00 0.49 0.00E+00 0.66 dose 87 6.68E-02 -0.10 4.40E-01 0.04 1.49E-02 0.12 dose 88 7.62E-01 -0.02 7.97E-11 0.43 3.13E-01 0.07 dose 89 2.50E-01 -0.05 0.00E+00 0.44 1.41E-01 0.07 dose 90 8.95E-01 0.01 3.20E-05 -0.27 1.71E-06 -0.31 dose 92 0.00E+00 0.44 0.00E+00 0.66 0.00E+00 0.79 Overall 0.00E+00 0.18 0.00E+00 0.20 1.05E-11 0.12 Table 105. Correlation of measures between public and private routines in flat classes.

126

% PRE VOID Project m µ M σ m dose 76 0 0.57 1 0.09 0 dose 77 0 0.25 0.53 0.12 0 dose 78 0 0.33 0.43 0.15 0 dose 80 0 0.12 1 0.2 0 dose 86 0 0.96 0.98 0.19 0 dose 87 0 0.35 0.91 0.18 0 dose 88 0 0.94 1 0.27 0 dose 89 0 0.57 0.61 0.14 0 dose 90 0 0.78 0.9 0.22 0 dose 92 0.44 0.59 0.65 0.05 0

% PRE ∀, ∃ % POST VOID % POST ∀, ∃ % POST OLD % INV VOID % INV ∀, ∃ µ M σ m µ M σ m µ M σ m µ M σ m µ M σ m µ M σ 0 0 0 0 0.09 0.18 0.06 0 0 0 0 0 0.09 0.29 0.06 0 0.29 0.46 0.1 0 0 0 0 0 0 0 0 0.05 0.08 0.01 0 0 0 0 0 0.78 0.87 0.14 0 0.62 0.82 0.17 0 0 0 0 0 0 0 0 0.89 1 0.39 0 0 0 0 0 0 0 0 0 0.38 0.38 0.16 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.5 0.64 0.2 0 0.5 0.5 0.09 0 0 0 0 0.01 0.02 0.01 0 0.32 0.72 0.21 0 0.25 0.6 0.18 0 0 0 0 0 1 1 0.27 0 0.12 0.14 0.04 0 0 0 0 0.37 1 0.2 0 0 0 0 0 0 0.02 0 0 0 0.88 0.17 0 0 0 0 0.02 0.04 0.01 0 0.33 1 0.19 0 0 0 0 0 0 0 0 0 0.8 1 0.14 0 0 0 0 0 0 0 0 0.21 0.6 0.1 0 0 0 0 0 0.21 0.29 0.12 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0.38 0.06 0 0 0 0 0 0.12 0.4 0.09 0 0 0.25 0.11 0 0 0 0 0.01 0.04 0 0 0.4 0.46 0.15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Table 106. Syntactic elements found in contracts (non-flattened classes).

127

Suggest Documents