SPECIFICATION VALIDATION
4.5.3 SPECIFICATION VALIDATION
In the previous section, we have written specifications of a number of ADTs, namely,
a stack, a queue, and a set. How do we know that our specifications are valid, that is, that they capture all the properties we want them to capture (completeness) and noth- ing else (minimality)? To bring a measure of confidence in the validity of these spe- cifications, we envision a validation process, similar to the process we advocated in Section 4.2.3, though this time (for the sake of simplicity) we focus solely on com- pleteness. We imagine that while we are writing these specifications, an independent verification and validation team is generating formulas of the form
stack h = y
for different values of h and y, on the grounds that whatever we write in our specifi- cation should logically imply these statements. Then the validation step consists in checking that the proposed formulas can be inferred from the axioms and rules of our specification. If they do, then we can conclude that our specification is complete with respect to the proposed formulas; if not, then we need to check with the verifi- cation and validation team to see whether our specification is incomplete or perhaps the validation data is erroneous.
For the sake of illustration, we check whether our specification is valid with respect to the formulas written in Section 4.3 as sample input/output pairs of our stack specification:
• V 1 stack pop init push a init push a top = a • V 2 stack pop init pop push a push b top top = b • V 3 stack init pop push a pop push a pop push a size = 1
• V 4 stack pop push a pop init pop push a top push a top push a pop empty = false • V 5 stack init pop pop pop push a push b push c top push c push b empty top = b
For V 1 , we find the following: stack(pop.init.push(a).init.push(a).top) = {by the init Rule} stack(init.push(a).top) = {by the second top axiom}
a.
QED
4.5 STATE-BASED SYSTEMS
For V 2 , we find the following: stack(pop.init.pop.push(a).push(b).top.top) = {by the init Rule} stack(init.pop.push(a).push(b).top.top) = {by the VX Rule pertaining to top} stack(init.pop.push(a).push(b).top) = {by the second top axiom}
b.
QED
For V 3 , we find the following: stack(init.pop.push(a).pop.push(a).pop.push(a).size) = {by the init pop Rule} stack(init.push(a).pop.push(a).pop.push(a).size) = {by the push pop Rule, applied twice} stack(init.push(a).size) = {by the size Rule} 1+stack(init.size) = {by the size axiom}
QED
For V 4 , we find the following: stack(pop.push(a).pop.init.pop.push(a).top.push(a).top.push(a).pop.empty) = {by the init rule} stack(init.pop.push(a).top.push(a).top.push(a).pop.empty) = {by the init pop rule} stack(init.push(a).top.push(a).top.push(a).pop.empty) = {by the VX rule, as it pertains to top} stack(init.push(a).push(a).push(a).pop.empty) = {by the push pop rule} stack(init.push(a).push(a).empty)
{by the empty rule} stack(init.push(a).empty) = {by the empty axiom} false. If the left-hand side logically implies false, then it is false.
QED
For V 5 , we find the following: stack(init.pop.pop.pop.push(a).push(b).push(c).top.push(c).push(b).empty.top) = {by virtue of the VX rules, applied to empty} stack(init.pop.pop.pop.push(a).push(b).push(c).top.push(c).push(b).top) = {by virtue of the second top axiom}
b.
QED
Because our specification has survived five tests unscathed, we gain a bit more confidence in its validity.
72 SOFTWARE SPECIFICATIONS