Monotonic Fault Removal
6.3.2 Monotonic Fault Removal
All programmers have war stories about a program that was running fine until they made a slight alteration to its code thinking they were improving it, when all of a sudden it started behaving erratically. Yet, fixing programs is supposed to make them behave better, nor worse. Whence the following definition.
Definition: Monotonic Fault Removal We let R be a specification on space S and we let p be a program on space S, which is written at some level of granularity as: p=p 1 ,p 2 ,p 3 ,…, p i ,…, p n . We assume that p i is a fault in program p with respect to specification R and we let component p i
be a program component on S. We say that the replacement of p i by p i constitutes a monotonic fault removal if and only if
110 FAILURES, ERRORS, AND FAULTS
the program p defined by p = C p 1 ,p 2 ,p 3 ,…, p i ,…, p n is strictly-more-correct with respect to R than program p.
Note the distinction between being a fault, which is a unary property that charac- terizes a component of program p, and being a monotonic fault removal, which is a binary property, that characterizes a faulty program part and its candidate substitution. Just because p i is a fault does not mean that any p i we substitute it with will be a mon- otonic fault removal. In other words, the fact that p i is a fault means that there exists (at least one) p i that will make p more-correct than p. To obtain a monotonic fault removal we need to find such a p i , whereas to prove that p i is a fault, it suffices to prove that such a p i exists.
As an illustration of the concept of monotonic fault removals, we consider again the program introduced in Section 6.3.1, and we let p be the program obtained from p by substituting condition c1 by c1 defined as:
A≤c&&Z≥c
Because this program is correct with respect to R, we know that dom R P = dom R , which we write as:
dom R P = s q list char
For the sake of comparison, we also write the domains of correctness of programs p and p :
dom R P = s q list char CHAR ,
dom R P = s q list char Z Clearly, we have dom R P ⊂ dom R P
dom R P = dom R Hence the transition from program p to program p via program p is uniformly
monotonic: with each fault removal, we obtain a more-correct program, until all faults are removed and we get a correct program.
Let us consider for a moment the case when we remove faults in reverse order: let p be the program obtained from p by changing condition c1 into condition c1 defined as above:
A≤c&&Z≥c
We write below the domain of correctness of this program: dom R P = s q list char CHAR
6.3 CONTINGENT FAULTS AND DEFINITE FAULTS 111
Figure 6.3 Ordering candidate programs by relative correctness.
Because this is not a strict superset of the domain of correctness of p with respect to R, the transition from p to p does not represent a monotonic fault removal. However, if we take program p and change statement b1 therein into b1 = (let+=1), we find program p , which is strictly-more-correct than p . Whereas the transition from p to p via p is uniformly monotonic, the transition from p to p via p is not, because p is not strictly-more-correct than p. These relations are illustrated in Figure 6.3.
As another illustrative example, consider the following specification on space S = natural:
R= s,s s mod 7 = s 2 mod 3 + 8 mod 7 And we consider the following three programs:
p = {s= 2*s; s= s mod 6; s= s+8;} p’ = {s= 2*s; s= s mod 3; s= s+8;} p” = {s= s^2; s= s mod 3; s= s+8;}
We find that p is not correct with respect to R. Indeed, dom R P = s 2s mod6 = s 2 mod3 , while dom(R)=S. We conjecture that the statement {s= s mod 6;} is a contingent
fault; to prove our claim, we consider program p , where this statement is replaced by {s= s mod 3;} and we prove that p is strictly-more-correct than p with respect to R. To this effect, we compare the competence domains of programs p and p . We find:
dom R P = s 2s mod 3 = s 2 mod3
112 FAILURES, ERRORS, AND FAULTS
We argue that dom R P ⊂ dom R P , since if 2s mod6 = s 2 mod3, then 2s mod6 is necessarily between 0 and 2, in which case 2s mod6 is identical to 2s mod3. Hence p is strictly-more-correct than p: indeed, p stems from p by replacing the statement {s= s mod 6;} by the statement {s= s mod 3;}. But we are not out of the woods yet: Program p is not correct with respect to R since the expression of the domain of competence of p , which is evaluated above, is not equal to the domain of R, which is S. We consider statement {s= 2*s;} in program g , and we resolve to replace it with statement {s= s*s;}, yielding program p . We find that p is correct with respect to R, since we have:
dom R P = dom R
The following table shows, for some values of the initial state s, the final states deliv- ered by programs p, p , and p ; we also show, by a shaded box, whether each program behaves correctly with respect to specification R. Note that while p behaves correctly once out of three times (whenever s is a multiple of 3), and while program p behaves correctly twice out of three times (whenever s is a multiple of 3, or 2 plus a multiple of 3), program p behaves correctly with respect to R every time (for all initial states).
P Value
Value Correct?
We have moved from program p to program p via program p by successive tran- sitions that yielded more and more correct programs; but things are not always so
6.3 CONTINGENT FAULTS AND DEFINITE FAULTS 113
smooth. If instead of changing the second statement of program p (from {s= s mod 6;} to {s= s mod 3;}) before the first (from {s= 2*x;} to {s= s*s;}), we changed the first statement first, we would have obtained the following program, which we denote by p o :
{s= s*s; s= s mod 6; s= s+8;}.
We are unable to prove that p o is more-correct than p, and for good reason: the table below shows that it is not, since the column that corresponds to p o does not
subsume the column that corresponds to P.
P Value
Value Correct?
We conclude this section by asking a simple question: do all fault removals have to be monotonic in practice? As we can see from the transitions from p to p in the two examples above, a substitution may be perfectly reasonable in the sense that it is bringing the program (syntactically) closer to being correct, and yet not produce a monotonic fault removal. While ideally it would be desirable if every substitution produced a monotonic fault removal, those that do not ought to be part of a sequence of substitutions that, together, yield a strictly-more-correct program. This is the case for the transition from p to p via p in the two exam- ples above.
114 FAILURES, ERRORS, AND FAULTS
Specification
Imperfect Successive design
correctness preserving transformations
Faulty
Successive correctness
program
enhancing transformations
Correct program
Figure 6.4
A framework for monotonic fault removal.