Minds and Machines

, Volume 21, Issue 2, pp 135–152

Specification

Authors

Article

DOI: 10.1007/s11023-011-9239-x

Cite this article as:
Turner, R. Minds & Machines (2011) 21: 135. doi:10.1007/s11023-011-9239-x

Abstract

The specification and implementation of computational artefacts occurs throughout the discipline of computer science. Consequently, unpacking its nature should constitute one of the core areas of the philosophy of computer science. This paper presents a conceptual analysis of the central role of specification in the discipline.

Keywords

SpecificationCorrectnessScientific theoryPhilosophy of computer science

Ubiquitous Specification

Specification occurs throughout the discipline of computer science. It operates at all levels of abstraction from the specification of simple machines and programs through to the specification of mainstream computational and theoretical systems. For example, in the design and construction of a compiler (Aho 1985) some notion of specification is involved: if a compiler is requested then the articulation of that request, however expressed, constitutes a specification. Similarly, a type inference system should satisfy some abstract notion of type inference (Pierce 2002) that provides its criteria of correctness, and any natural language translation system (Alan 1994) must conform to some specification; presumably, it should, in a sense determined by the specification itself, translate correctly.

Indeed, despite much popular propaganda to the contrary, programming and specification are not easily separable activities. Properly understood, there is no escaping some level of specification. Programming is not an aimless activity, and any articulation of its goals constitutes a specification. Furthermore, any subsequent rational use of a suite of software requires some description of what it does. While this description may be constructed post hoc, and quite informal, logically it must still, at some level, spell out of the function of the program.1

Indeed, it is often said that the role of specification is to describe the artefact not how to build it. However, while this characterization has the merit of being succinct, it hides and suggests a good number of clarifying questions.
  1. (1)

    What is the logical role of specification? In particular, how are specifications connected to definitions?

     
  2. (2)

    What is the relationship between a specification and an artefact? What does it mean to say that an artefact has been correctly constructed and how is this established?

     
  3. (3)

    What is the difference between a program and a specification? For instance, is it that specifications are descriptive while programs are prescriptive?

     
  4. (4)

    How do specifications differ from scientific theories?

     

While some of these issues are implicitly addressed in the relevant computational literature e.g. Morgan 1990; Jones 1986; Van Vliet 2008), there is little sustained conceptual analysis. The aim of the present paper is to contribute to the latter.

The Articulation of Specifications

In practice, specifications are expressed in a host of languages and formalisms that range from the vernacular through to specialized specification languages. Some of them are graphical in content e.g. UML (Grady Booch 1999) and many others are based upon some logical notation e.g. Z (Woodcock 1996; Spivey 1998; Diller 1990; Potter 1991), B (Abrial 1996) and VDM (Jones 1986; Dawes 1991).

To illustrate the various vehicles of specification we specify a rudimentary computer store in several guises: a natural language description, a graphical representation, and a more formal one. We begin with the vernacular account.
  1. 1.

    The store has named locations that hold numerical values. Each location holds at most one value.

     
  2. 2.

    A Lookup operation that extracts the content of named locations.

     
  3. 3.

    An Update operation provides the means of changing the contents of a location.

     
  4. 4.

    When the location’s contents are changed, the contents of the new location should be the only thing changed.

     
This description of the store tells us about its structure i.e., there are locations that hold values. In order to manipulate the store there are two operations, Update and Lookup. In addition, the definition (part 4) provides the constraints that the device must satisfy. What it does not do is tell us how to build it or what it is to be made of. This is close to what the literature refers to as a functional specification (Van Vliet 2008). Typically, this describes what is needed by the system user and the requested properties of inputs and outputs.2
There are many different ways of conveying this information. For example, we could utilize a graphical representation that employs some form of activity diagram. In particular, we might represent the Update operation as follows (Fig. 1).
https://static-content.springer.com/image/art%3A10.1007%2Fs11023-011-9239-x/MediaObjects/11023_2011_9239_Fig1_HTML.gif
Fig. 1

The update operation in UML

Of course, to express specifications as familiar and informative as those provided by the vernacular version, we would need to supplement this with some semantic account of these diagrams. We might for example employ UML diagrams and their semantic interpretation (Grady Booch 1999).

Finally, we might provide a more explicitly mathematical account based upon set theoretic notions. The following version (call it C) takes the basic domains of the vernacular specification to be sets and expresses the operations as functions operating on these sets.
  1. 1.

    Store, Location and Values are three sets that represent the store itself, the locations and the values.

     
  2. 2.

    Lookup: Store ⊗ Location → Values is a partial function from the Cartesian product of stores and locations to values.

     
  3. 3.

    Update: Store ⊗ Location ⊗ Values ⇒ Store is a total function from the Cartesian product of store, locations and values to the store.

     
  4. 4.

    These operations are governed by the following conditions. For all stores s, locations x and values v we have:

     
  5. i.

    Lookup(Update(s,x,v),x) = v

     
  6. ii.

    Lookup(Update(s,x,v),y) = Lookup(s,y), where x ≠ y and Lookup(s,y) is defined

     
This encodes the informal account in the language of set theory. It actually makes matters more explicit and uncovers unconsidered aspects. For example, it draws our attention to the fact that we need to do something special when the location we are examining is empty. Indeed, even more demands might be made. For instance, we might set an upper limit to the number of locations in the store or constrain the class of values to be numbers of a certain size. On the other hand, our store might be specified in a very loose and informal manner.

A store should hold values in locations.

To begin with at least, this might be all we are given by way of a specification, and much may be left implicit such as the fact that we need to change values in locations. The level of detail and generality in a specification can vary greatly.

To cope with the complexity and size of actual systems, many mechanisms of abstraction have been developed. The Z specification language has a built-in calculus of schema that facilitates the construction of complex specifications in a modular fashion. Complementary approaches have pursued notions of abstraction based upon patterns. The following is the object adapter-pattern expressed in the specification language UML. The adapter hides the adaptee’s interface from the client.
https://static-content.springer.com/image/art%3A10.1007%2Fs11023-011-9239-x/MediaObjects/11023_2011_9239_Figa_HTML.gif

Furthermore, it is not untypical that specifications are given at a very general level using existing notions. In particular, in the specification of a large system we might only be told that there are various components (e.g. a compiler, a word processor, a database, etc.), and be informed of their relationships.3 Such specifications are informative because they employ notions such as database, word processor etc. which have known functions.4 Further detail may not be required for a top level architectural specification.

It is clear that specification is a heterogeneous enterprise carried out in a large variety of languages and formalisms, with layers of complexity, generality and degrees of detail. However, there is a logical core to specification that is common to all such languages and formalisms.

Specifications as Definitions

While specifications may be expressed in a variety of ways, whatever form they take, one thing they do, almost incidentally, is to define new named devices, structures and systems. Consequently, to better understand the logical form of specifications, we need to look more generally at definitions.

The central literature on definition (Gupta 2008; Horty, Frege on Definitions, 2007; Robinson 1950) recognizes several different kinds and flavours of definition: real and nominal, dictionary and ostensive, stipulative, descriptive and explicative. However, it would seem that definitions in computer science come closest to being stipulative definitions. These involve the introduction of a new term (or even an existing term) that is given a specific meaning in a given context. For example, the following defines a new numerical function.
$$ New(n) = n^{3} + n^{2} - 7 $$
This stipulates a function called New. The following is the standard definition of the Ackerman function.
$$ A(m,n) = \left\{ {\begin{array}{*{20}c} {n + 1} \hfill & {{\text{if}}\, m = 0} \hfill \\ {A(m - 1,1)} \hfill & {{\text{if}}\, m > 0\,{\text{and}}\,n = 0} \hfill \\ {A(m - 1,A(m,n - 1))} \hfill & {{\text{if}}\, m > 0\,{\text{and}}\,n > 0} \hfill \\ \end{array} } \right. $$

Originally, this was given via a stipulative definition. Indeed, much original mathematics involves this kind of definition in that new notions are introduced and investigated. These definitions involve no commitment that the assigned meaning of new term agrees with any prior use. Moreover, stipulative definitions cannot be correct or incorrect.

A little reflection suggests that specifications can act as stipulative definitions of new devices. For example, C can be taken to define an abstract machine. Likewise the following Z schema uses set theory to define an abstract state of some kind, presumably of a library system.
https://static-content.springer.com/image/art%3A10.1007%2Fs11023-011-9239-x/MediaObjects/11023_2011_9239_Figb_HTML.gif
Finally, the following is the core of the handover protocol for the GSM Public Land Mobile Network expressed in the ∏-calculus.
$$ car(talk,switch) = talk.car(talk,switch) + switch(talk^{\prime } ,switch^{\prime } ).car(talk^{\prime } ,switch^{\prime } ) $$

In the ∏-calculus this is taken to define a process. Of course, the underlying ontology alluded to here (abstract machines, sets, processes) emanates from the perceived semantic interpretations of these languages and formalisms. It is these that give substance to the new named things we are defining. We shall have a little more to say about this later, and much more on another occasion. At this point we are only claiming that these specifications may be seen as stipulative definitions that introduce new abstract devices.

Moreover, this is true even when the specification is given in vernacular form. In particular, our informal version of C defines an abstract machine that has some generic notion of location, state, lookup and update. This is made more exact by C.5 Indeed, while formal accounts enable us to avoid ambiguity, uncover hidden assumptions, and explicitly articulate an underlying ontology, most of the time we tolerate a degree of imprecision in specification. The difference between a formal specification and an informal one is matter of degree.

Definitions as Specifications

However, by itself a stipulative definition is not a specification. Indeed, it may have some completely different purpose. For instance, a definition may form part of a mathematical exploration or even part of a legal decision. But whatever form it takes, and whatever its level of precision, a definition functions as a specification only when the definition is taken to point beyond itself in that it is taken to tell us what to build or construct. A specification provides a description of the proposed artefact. In turn, this provides substance to their logical role which is to provide a criterion of correctness or malfunction for purported artefacts. In this role, its function is not mathematical or formal but practical. For example, our abstract machine definition C is taken to function as a specification when it is taken to dictate the construction of another artefact. In particular, we might take it to provide the specification for the construction of a physical machine. The specification then tells the machine builder what to build, and once built to inform her whether she has it right. If she constructs a food mixer, something has gone wrong, and it is the specification that determines this. In order to repair matters, we may wish to know how the mistake was made, why the builder got it wrong. Perhaps she does not understand predicate logic. But why the mistake was made is one thing; why it is a mistake is another. Only the latter is in the remit of the definition functioning as a specification. This concentration on the logical role of specification parallels the distinction in the philosophy of science between the context of discovery and the context of justification where the former deals with the process of discovery and the latter with its justification (Reichenbach 1938). A similar distinction is made in the philosophy of law between the actual procedures a judge follows to reach a decision and the legal correctness of the final decision i.e., its legal justification. In the case of specification the distinction unpacks as the difference between the process of constructing the artefact and the justification of its correctness.

In summary, it is the act of taking a definition to have normative force over the construction of an artefact that turns a mere definition into a specification. This normative role of specification is implicitly stated in the following remarks of Kripke (Kripke 1982).

Actual machines can malfunction: through melting wires or slipping gears they may give the wrong answer. How is it determined when a malfunction occurs? By reference to the program of the machine, as intended by its designer, not simply by reference to the machine itself. Depending on the intent of the designer, any particular phenomenon may or may not count as a machine malfunction. A programmer with suitable intentions might even have intended to make use of the fact that wires melt or gears slip, so that a machine that is malfunctioning for me is behaving perfectly for him. Whether a machine ever malfunctions and, if so, when, is not a property of the machine itself as a physical object, but is well defined only in terms of its program, stipulated by its designer. Given the program, once again, the physical object is superfluous for the purpose of determining what function is meant.

Whether a machine malfunctions is not a property of the machine itself but is determined by its specification. Indeed, this normative role of specification makes it evident that a specification not only can be viewed as the definition of an abstract device, but must be so viewable. Physical devices could not themselves act as definitional mediums. Otherwise, we could not provide a stable notion of correctness: what is true of the physical device today might not be so tomorrow.6

It should go without saying that any such analysis of specification is an idealization; one that parallels the idealized role of theories in science. The notion of a scientific theory (Rosenberg 2000; Chalmers 1999) is clearly not to be taken as an exact reflection of practice; it is a rational reconstruction of practice intended as a characterization for philosophical purposes. Our account of specification involves a similar rationalization. There are several ways in which this picture might be taken to be too simplistic.

Many software projects just evolve in unpredictable ways. For example is there a specification for a search engine? Yes. It has to be a search engine not a language translator. It may be vague, but it is still a specification. Of course, a specification may have to be changed because a client changes her mind about the requirements or because the artefact may be impossible to build. The underlying definition may be logically absurd in the sense that there are no instances. Furthermore, even if logically feasible, the artefact may still be impossible to construct for a whole variety of practical reasons. The underlying physical laws may prohibit matters; the designer may not know the right physics. There may also be cost limitations that prevent construction. In these cases, the current specification will have to be given up or at very least require modification and further clarification. However, all this concerns the processes involved in specification formulation and artefact construction rather than the logical role of specification. It concerns the context of discovery rather than the context of justification.

Furthermore, the relationship between specification and artefact maybe somewhat loose; an artefact may not exactly meet its specification. Some issues are more significant than others. A computer may meet its specification if the on/off button is tarnished but not if the CPU does not compute. Generally, the artefact has to satisfy its specification to the degree that it is fit for use. This is a part of the caveats that govern specifications in use, and may be taken as part of the meta-theory of specification: some looseness is tolerated but there has to be some general demand that the artefact be fit for use. Of course, there is considerable room for vagueness and argument about what this entails.7

Specification and Function

Generally, artefacts serve a purpose (e.g. they run an air traffic control system or a nuclear power plant), and this is usually referred to as the artefact’s function (Franssen 2009; Kroes 2006). Such functional descriptions govern the artefact in an atemporal way. They answer the question: what is it for? In contrast, specifications are taken to be prescribed in advance of the artefact construction and guide the constructor or implementer. Indeed, this might be taken to suggest a more substantive role for specification i.e., to provide a methodology for the construction of the artefact. For example, there are refinement techniques in computer science (Morgan 1990; Potter 1991; Diller) that allow the massaging of specifications into programs. In this employment, a specification not only tells us what to build but also forms part of the road map for artefact construction. However, this is not part of the specification, and certainly not part of any functional specification, but part of a methodology of program construction. The method by which we arrive at the artefact is a separate issue to its specification. The latter dictates no such methodology.

The only substantial difference between a functional specification and functional description is a possible temporal one: if it is given ahead of the construction it is a specification whereas if it is given after construction it is a functional description. Logically they may have the same form and both provide a criterion of correctness.

Computational Artefacts

This provides a general account of specification and correctness. However, to proceed further with our analysis, and in particular, to explore how correctness is to be characterized, we need to pay attention to fact that there are different kinds of computational artefact and this impacts upon the nature of correctness.

Computational artefacts include programs, algorithms, programming languages, databases, compilers and interpreters, operating systems, physical and abstract machines, type inference systems, web browsers, natural language systems etc., etc. This is a very motley crew of things and it is not immediately clear whether the notion of correctness is the same for all such artefacts. Indeed, there appears to be a major difference that emanates from a basic ontological distinction.

It is generally supposed in philosophy that every object is either abstract or concrete (Rosen 2001; Hale 1987; Zalta 1983).8 Indeed, we have already alluded to this distinction in our discussion of the abstract nature of definitions and specifications. There are a variety of ways in which this distinction has been drawn. One way characterizes an object as abstract if it has no spatial/temporal existence. A second argues that abstract objects are causally inert. A more recent attempt seeks a characterization in terms of Frege’s principle of abstraction (Hale 2001). Unfortunately, none of these characterizations is universally accepted.

Fortunately, we do not need to decide such issues here; we need only observe that, despite this lack of clarity concerning characterizing features, there is almost universal agreement about how to classify certain paradigm cases (Rosen 2001; Jacquette 2002). For example, it is universally acknowledged that algorithms and topological spaces are abstract objects, whereas hard drives and computers are concrete physical ones. Although, programs are often taken to have both an abstract and physical manifestation (Moor 1978; Colburn 2000), the implications of this will be addressed in our discussion. There is also general agreement that whatever is the right characterization of the abstract/physical divide, the paradigm cases of physical artefacts are subject to chains of causation and to empirical investigation, whereas the paradigm cases of abstract ones are physically inert and are only subject to conceptual or mathematical investigation.

This ontological distinction has some considerable impact upon the appropriate form of correctness for the various artefacts of computer science. We begin with the physical ones.

The Specification of Physical Devices

Presumably, a physical store that meets the specification of our abstract one will consist of some physical means of storing information in named physical locations, where every location somehow holds values but holds at most one value. In addition, we need physical update and lookup mechanisms, and the whole physical device must satisfy the conditions i and ii with the physical state and operations replacing the abstract ones i.e., for all physical states S, locations X and values V we have:
  1. i.

    Lookup(Update(S,X,V),V) = V

     
  2. ii.

    Lookup(Update(S,X,V),Y) = Lookup(S,Y) where X ≠ Y

     

Of course this is not a complete description of a physical machine; it is not intended to be. There will be many ways in which such a device can be constructed. Its location slots can be made of any materials that come to hand, and the physical operations constructed with plastic handles or steel girders. The functional specification does not prescribe such details; it only provides some constraints that it has to satisfy: whatever it is made of it must form a physical model of the assertions of the abstract machine i.e. they must be true when interpreted as assertions about the physical one. In this sense, we require that the physical machine forms a physical model of the given specification.

The specification given by the abstract machine, and particular i and ii, provide the criterion of correctness for the physical one. Furthermore, their truth is now a claim about the physical machine; the constraints now act not as mathematical assertions but as empirical demands on the physical device. They must be tested accordingly i.e., we run some tests and observe the results. Suppose that we run the system on a range of examples. If our tests fail on one example, (i.e., we do not get the results consistent with the specification) then we may conclude that the system does not meet its specification i.e., the misbehaviour of the system is evidence that it does not meet its specification. So for example, if when the machine is updated with input 3 into location z, it puts 7 in location u, then the physical machine has malfunctioned.

Conversely, what if it meets its specification for a range of examples? If these examples are judiciously chosen, we might then conclude that the physical device meets its specification. Indeed, often in practice, associated with a specification, are various procedures that spell out how it is to be determined that the specification has been met. They provide guidance for the correctness evaluation for each technical requirement. But whatever form such procedures take, the verification of correctness is always an empirical matter that offers no absolute guarantees that the physical device will not subsequently fail.

But what if our machine is finite with a finite number of locations and a bound on the size of numbers that may be entered etc.? Given this we could, in principle, check all possible combinations of operations and state configurations. Does this change the status of our correctness claim? No. It is still an empirical claim about a physical device; it is not a mathematical or formal claim about an abstract one. In particular, even after an exhaustive process of testing, there is no guarantee that the next operation will be successful. Its cogs and handles may fail to function or its locations may get blocked. The correctness of a physical artefact is always an empirical matter.

The Specification of Programs

We now turn to the very different picture generated by abstract artefacts: we consider the specification of programs. We have argued in (Turner, Programming Languages as Mathematical Theories, 2010; Turner, Understanding Programming Languages, 2007) that programming languages must be given a semantic interpretation in terms of an abstract rather than a physical machine. The arguments are driven by rule following considerations, and the need to have a stable notion of correctness for the use of the constructs of the language (Kripke 1982; Boghossian 1989; Gluer 2008). A consequence of this is that programs themselves are (semantically) abstract objects. We shall have more to say about the sense in which they might be said to have an empirical aspect, and the implications this has for the nature of correctness, later. Initially, we need to do a little preparatory work.

In order to program our store we require some form of machine language. Indeed, this is largely determined by the basic operations themselves. The language has a basic machine instruction
$$ x: = E $$
and programs are sequences (;) of these.
$$ P:: = x: = E\left| {x: = E;P} \right. $$
where an expression (E) is either a numeral or a variable. The following is a simple program that apparently swops the values in locations x and y.
$$ z: = x;x: = y;y: = z $$
In order to construct or understand this or any program in this language, more than the syntax is required; some semantic information about the language must be supplied. There are many techniques for providing one (Stoy 1977; Fernandez 2004) but in the present context, the natural and easiest way is via its impact upon our store i.e., via a notion of execution we provide a form of operational semantics (Fernandez 2004; Plotkin 2004) for the language.
  1. (1)

    The execution of x: = E in a store s returns the store that is the same as s except that the value v of E replaces the current value in location x i.e., Update(s, x, v).

     
  2. (2)

    If the execution of x: = E in s yields the store s′ and the execution of P in s′ returns the store s″, then the execution of x: = n; P in s, returns the store s.

     
Where the value of a variable x in a store s, is Lookup(x, s). We shall write
$$ \left\langle {P,s} \right\rangle \Downarrow s^{\prime } $$
to indicate that executing P in store s terminates in s′. Using this we could write 1 and 2 in a more precise way, but the above informal account will be enough for our present purposes.

We may now move on to our first examples that involve the specification of abstract artefacts, namely the specification and correctness of programs. To illustrate matters we specify a swop operation as a relation between the before and after stores of our abstract machine.

For all stores s, locations x and locations y we have:
$$ (\user2{S})Swop(s,s^{\prime } ,x,y) \leftrightarrow Lookup(x,s^{\prime } ) = Lookup(y,s) \wedge Lookup(y,s^{\prime } ) = Lookup(x,s) $$
Swop is a description of the relationship between the new and old stores. It defines a new relation between stores and locations i.e., it states that the values in the locations are switched. Unlike the program
$$ (\user2{P})z: = x;x: = y;y: = z $$
S does not tell us how to do the swopping. It merely informs us how the before and after states are related.
What does it mean for P, the artefact, to be correct relative to the specification S? Given its operational semantics, we may state the correctness conditions for the program P, as follows. For all stores s, s′,
$$ \left\langle {P(x,y),s} \right\rangle \Downarrow s^{\prime } \,implies\,Swop(s,s^{\prime } ,x,y) $$

The initial and final stores, together with the input locations, satisfy the specification. This is a mathematical assertion, and any proof of correctness would need to be a mathematical proof. This represents the traditional mathematical notion of correctness for abstract artefacts.

There are variations on it. Checking that a specification and a program are of the same type provides a much weaker notion of correctness (Aho 1985; Milner 1978) that may be automatically checked.9 Assuming the mathematical correctness of the type checking algorithm, this is still a mathematical notion of correctness. However, generally type systems are logically weak and offer meagre notions of correctness that guarantee little. The type of a program may be a very uninformative guide to its semantic content and behaviour. For instance, knowing that a program that inputs two numbers and outputs another does not tell us whether it is addition or multiplication. However, type systems can have considerably more logical content, and then type correctness and logical correctness may coincide (Bengt Nordström 1990; Turner, Constructive Foundations for Functional Languages, 1991).

In summary, abstract devices are subject to mathematical analysis while physical ones are only amenable to empirical testing and verification. This is the traditional picture. However, it may be challenged. We shall get to this shortly, but first we draw out a further aspect of program correctness.

Intentional Stance

We may now address another of our concerns that pertains to the difference between programs and specifications. What is the difference? Can programs and specifications be distinguished on linguistic grounds? For example, are programs imperative and specifications descriptive? With our example, this appears to be so. It is also consistent with the original characterisation that the role of specification is to describe the artefact not how to build it. However, it is misleading. Logic based languages (under their declarative semantics) are not imperative, and nor are functional ones such as Haskell and SML.

Another suggestion locates the distinction between the underlying languages and their supporting implementations: programming languages have an implementation, specification languages do not. But is this meant in the sense of there being an existing compiler or interpreter? If so, a language might be deemed a specification language simply because no one has bothered to implement it. We might modify matters by insisting that programming languages are those languages that have an implementation in principle, whereas specification languages are those that of necessity do not. Presumably, the reason they do not is that specification languages permit one to express notions that are not Turing computable. However, it is unclear whether such non-computable specifications are necessary in practice (Jones 1990; Fuchs 1992). It is true that there may be things that one wants to say about programs that cannot be expressed within the program body (Turner, Computable Models, 2009). For example, we may wish to insist that a function is total. However, this is not part of the functional specification. Rather it is a derived meta-property of the program. The more significant distinction between specifications and programs lies elsewhere.

Generally, what we take to be the specification and what we take to be the artefact or program is not a matter of linguistic form or whether one is written in a specification language that has no implementation, and the other is written in a programming language that does. Such characterizations seem to miss the most important conceptual point: something is a specification when it is given correctness jurisdiction over an artefact.10

To emphasize this point consider the following implementation of the Ackerman function in the programming language MirandaTM.

ack 0 n = n + 1

ack (m + 1) 0 = ack m 1

ack (m + 1) (n + 1) = ack m (ack (m + 1) n)

This is quite close in form to the mathematical definition. Finally, the following is an implementation in the programming language C. This moves us farther away from the original. Certainly, the syntax is now different.

unsigned int ack(unsigned int m, unsigned int n)

{

if (m == 0)

return n + 1;

else if (n == 0)

return ack(m  1, 1);

else

return ack(m  1, ack(m, n  1));

}

The original definition could be taken as a specification of the MirandaTM version. Correctness is then relative to the mathematical definition. In turn, the MirandaTM version could be used as the specification of the C version. Conceptually, the important difference between these three has little to do with their linguistic forms. Nor has it much to do with the existence of an implementation. Our intentional stance determines what we take to be the specification: something is a specification if we give it normative force over the construction of an artefact, which in this case is another program.

The Argument from Complexity

Despite the fundamental differences between abstract and physical artefacts, it is argued that the complexity of many contemporary computational systems, irrespective of their ontological nature, demands that they be treated as physical systems. In particular, this is taken by some to apply even to software systems where the arguments are aimed at the complexity of the required mathematical correctness proofs (De Millo 1979). For example, it might be argued that, even if we treat it as an abstract system, concentrating on the code and assuming it to run on an abstract machine, and ignoring its physical implementation, an air traffic control system that consists of millions of lines of code, cannot be shown to be correct in the purely mathematical sense. This is not a logical impossibility but a practical one: the complexity of the system makes it infeasible. In other words, even if we view it ontologically as an abstract device, we must treat the system as a natural artefact whose correctness is established by testing and verification. For all intents and purposes complex computational systems are physical systems whose assertions of correctness are on par with that of our physical machine. Even if some mathematical techniques may be incorporated into the overall correctness process, there will always have to be some elements of testing and verification. Although this may be disputed, (Asperti 2009) it seems to reflect much contemporary practice. What is clear is that computational systems consist of a mixture of abstract and physical artefacts and some testing and verification is inevitable. Our main interest is in clarifying the nature of correctness and verification.

Specification and Theory

Is the process of testing and verification a scientific enterprise in that specifications act as scientific theories of computational artefacts. Indeed, there are some authors who seem to advocate such a view even for simple physical devices.11 In particular, one might argue that the abstract definition of our simple machine is to function as an empirical claim about the concrete machine that is to be constructed. But is this perspective defensible? Do specifications function as scientific theories of computational artefacts?

Scientific theories are meant to be descriptive of nature and the way it functions (Rosenberg 2000; Chalmers 1999). They are intended to be predictive in that they enable us to predict how the world will behave in the future, and they are meant to be explanatory in that they explain what has happened in the past and why it has happened.12 However, such theories are always up for revision: they are postulated, tested and amended. So, while their generality provides explanatory and predictive power, they pay the price of providing defeasible knowledge. Most importantly for our purposes, when there is a mismatch between the theory and the world, the world is not to blame; scientific theories may have to be given up in the light of experimentation.

While it is true that specifications may have logical consequences, and these can act as predictions about the properties of the constructed device, and become the focus for testing and verification, it is the artefact that is being tested not the specification. Specifications are not descriptions of the world; they do not provide knowledge that something is the case. In their central logical role they are normative in their function: they provide a notion of correctness.13 If the device fails to satisfy the specification, we say that the device has malfunctioned, and does not reflect the designer’s intentions. If it fails, the device needs to be rebuilt. Specifications are not intended to be explanatory. At least they are not intended to provide scientific explanations (Woodward 2009). While one may ask ‘why did the machine malfunction?’ acting as a specification, C does not tell us; its role is only to tell us what it means to malfunction. The specification of our abstract machine C neither predicts that the machine will behave correctly nor causes the machine to behave correctly.

In short, specifications are not intended to be a scientific theory of anything. If my computer does not meet its specification, I do not expect the manufacturer to supply me with a revised specification, which is what I would expect if it were functioning as a theory of the device. I expect to be given a computer that actually meets the original specification. With specifications it is the artefact that is correct or not; with theories it is the theory.

Undoubtedly, these characterizations oversimplify the logical roles of both specifications and theories. For one thing, scientists do not change their theories as easily as this simplistic characterization suggests. So-called normal science, where a theory dominates, can last some considerable time. Indeed, major changes of theory, the big paradigm shifts, happen quite infrequently, and during the periods of normal science, theories play a more normative role. In a parallel way, the engineer does not hold onto the specification no matter what. Its normative status may be given up in the light of continual practical failures to build a device that satisfies it.

Model Construction

However, despite these differences, there are other aspects of complex systems that seemingly close the gap between specifications and scientific theories. We have already discussed the claim that the complexity of such systems prohibits mathematical investigation. This is already epistemologically disappointing. But matters are claimed to be much worse: the system may also be too complex to even test directly. In particular, the size of the state space may be so large and complex that even direct testing is infeasible. In practice, the construction of models or theories that approximate the behaviour of complex systems is the best we can do. In particular, in order to study the system we may be forced into the construction of an idealmodel of the system (Anguis 2010).14 One such technique is referred to as model-checking (Baier 2008). Here idealized models of the system are constructed using the apparatus of modal logic and possible worlds. Temporal logic specifications are checked algorithmically against such models (Edmund and Clarke 1999). This complicates our simple picture of the clean separation between scientific methodology and specification.

However, simply because there is a need to construct models of complex systems does not mean that we are engaged in the construction of a scientific theory or model for the same purposes as natural science. At the stage at which the model is being constructed, the process may well resemble standard model construction in science (Rosenberg 2000). In particular, if things go wrong and the model does not fit the system, then we throw out the model. In this respect, the methodology resembles that of scientific theory/model construction.

Despite this, the core goal of the enterprise is not the construction of the model. It is only a means to an end. Its primary function is to stand proxy for the system. The principle goal is to establish the correctness of the system. In particular, once the model is constructed and tested it becomes the artefact. Our intentional stance changes. If things go wrong, although the model will still be blamed, it is not because it has got the world wrong. Rather, it will be blamed as an artefact i.e., because it does not conform to the specification. The normative role of the specification is still in force. The only caveat is that it now governs the system indirectly via the model: the specification now has normative force over the system via the model. In contrast, in the scientific endeavour, it is the world that holds sway over the model.

The Argument from Change

However, the need to construct theories of modern computational systems can show itself in a different way. Even if a computational artefact possessed an original specification, subsequent modifications and changes make it largely irrelevant. Updates and modifications may change matters beyond recognition. Consequently, to uncover the function of the artefact we need to treat it as a natural device that has an existence of its own. Via testing and abstraction we gradually unpack its use and properties. In doing so we might be taken to be building a theory of it as a natural object. Original specifications are superseded by theories of the system. Every revision turns the artefact into a natural one in need of investigation. There is even an approach (O’Hearn 2010) where an automated reasoning tool generates new hypotheses about the system starting from the system itself.

Let us take it as read that some kind of post hoc theory construction is necessary for the subsequent use of the artefact. What is at issue is the precise role it is supposed to play in this use. Presumably, once the theory has been constructed, the artefact may be put to use either as a stand-alone device or as part of an embedded system. In either case, the theory no longer functions as a scientific theory of the artefact but as a post hoc functional description of it. In particular, when we use it as a component in an embedded system, we employ the constructed theory as a functional description. At this point, our intentional stance changes. As a component of such a system we need to know what it does. However, the latter no longer functions as a theory of the device but as a functional specification. Of course, subsequent information about the system may involve a revision of the theory, and our intentional stance may switch yet again.

This difference between the two roles has little to do with the representation and form of the specification or theory. The difference concerns only the intentional stance we take towards it at any given time in its employment: defeasible descriptive theory or normative functional description.

Footnotes
1

Extreme programming, and even cowboy coding, may have very loose design strategies and no specified methodology of development, but they still have some goals.

 
2

We shall not try and be precise about the notion of a functional specification. This rough characterisation will serve our purpose. Nor shall we be concerned with the full range of practical aspects of software engineering that involve requirements capture and design methodologies. Here we shall concentrate on what we take to be the central philosophical issue.

 
3

“The software architecture of a program or computing system is the structure or structures of the system, which comprise software components, the externally visible properties of those components, and the relationships among them.” (Bass 2003).

 
4

Indeed, they are candidates for computer science examples of artificial kinds (Franssen 2009). There is much more that needs to be explored here, but it requires more space than we presently have.

 
5

With more complex specifications we have to work much harder. While choosing the appropriate underlying ontological setting makes it possible to make precise most aspects of a specification (Turner R, Computable Models, 2009), it is a non-trivial task.

 
6

One might suggest that ostensive definitions may be used as the basis of specification, and these may be based on physical devices. Suppose I request you to build me a stick of length one metre. Is this not to use a physical object, the stick in Paris, as the basis of a specification? Not in the sense that no abstract notion or device is involved. The length Metre is not something that changes with the length of the Paris stick. Once baptized, the length is fixed; it is the same in all possible worlds. There is clearly much more that might be said here, but it would take us too far afield.

 
7

Perhaps the artificial kinds of computer science are encoding some notion of real essence for these artefacts and thereby determine what fit for use might be taken to be.

 
8

This is not intended to be the same as the so called software/hardware distinction (Moor 1978).

 
9

Much the same is true of those object-oriented approaches to software design e.g. (Eden 2011).

 
10

Something akin to this is implicitly asserted in terms of clients and programmers, in (Morgan 1990).

 
11

…the other is to interpret rules and axioms of form (C) as empirical claims concerning the possible behaviour of the target machine thereby described… (Fetzer 1988).

… (C) is actually a prediction of what will occur when statement S is ultimately executed…It is a static prediction of its later dynamic execution (Colburn 2000).

 
12

We shall now go more deeply into the debate about the nature of explanation and its connection with causation. The main focus here is in the role of testing and verification of scientific theories.

 
13

Of course, specifications and designs do employ scientific and other knowledge; knowledge about how to construct the artefact. Often the difference is characterized as the difference between knowing how and knowing that (McCarthy 2006).

 
14

The difference between a model and a theory is controversial and not that significant for the present discussion since the central point may be phrased in terms of theories or models. Anguis (2010) contains a very clear account of this distinction as applied to program construction.

 

Copyright information

© Springer Science+Business Media B.V. 2011