Taxonomy/1. Quality/06. Software

Uit Werkplaats
< Taxonomy‎ | 1. Quality
Versie door Hanno Wupper (overleg | bijdragen) op 23 mei 2008 om 07:41 (navigatio was wrong)
(wijz) ← Oudere versie | Huidige versie (wijz) | Nieuwere versie → (wijz)
Ga naar: navigatie, zoeken
RationalitySquare.gif

Taxonomy
of Computer Science
Hanno Wupper
Hans Meijer
Angelika Mader
Stijn Hoppenbrouwers
Mieke Boon


 © comments


Related:

{Taxonomy/Intro|Rationality Squares and Correctness Theorems can be applied to all artefacts, whether they contain computer programs or not. This chapter places hardware and software into their context.}}

language confusion

Note for software engineers. If you were educated in the culture of classical software engineering you may have found the previous chapters confusing. Your discipline had a tendency to abstract from computer hardware and to identify the physical artefact computer together with a program with its blueprint: the program text. Thatg is because in the area of software, →realisation as defined here was is so trivial that software engineers reuseuse the word "realisation" for quite something else, which in ouw view is a special case of a transformation of formulae in the mathematical world.

This chapter tries to make explicit what in software engineering is treated implicitly.

The hardware of a contemporary computer is a very complex artefact, extremely difficult to design and realise. Its specification, however, is relatively simple: a universal machine. Due to its universality one often abstracts from its existence altogether. This can make reasoning simpler, but it can also lead to misunderstandings.

The software in a computer, viz. a program, is both at the same time: a physical part of a physical artefact (for example in form of magnetism in the memory) and its own blueprint (in the form of a text in some higher or lower level programming language). The realisation of the latter consists of some form of translation, followed by loading the result into working memory. This is so well-understood and fast, that one often abstracts from it. Again, this can make reasoning simpler, but it can also lead to misunderstandings.

In our context, a computer program P, be it high or low level, should be considered as a blueprint as long as it is developed, written down, proved correct, or compiled. When "the same" program is loaded in program memory of a computer, however, it is a physical phenomenon that can be observed, usually as some form of magnetism. We write load(P) to state that program P had been loaded into the computer under discussion.

Programmable machines

A special purpose computer is an artefact of 2 parts
  • a special purpose program, the text of which is used as blueprint of the entire artefact
  • a machine, which is traditionally not mentined in the blueprint at all

Assume that a specification S is given, which specifies behaviour in terms of observables at some input/output ports of a controller. Assume we want to implement that controller by a suitably programmed computer. What does that mean in our framework? The artefact we want consists of two parts:

a computer 
That is a universal machine which "understands" a certain programming language. Maybe we already have that computer, maybe we will buy it.
a program 
This must turn the universal machine into a special-purpose machine such that the two together are an implementation of S. Of course, that program will have to be...
  • written in the language the machine understands and
  • loaded into that machine.

The correctness theorem for that artefact of two parts must be something like

UM(L) ∧ X ⇒ S

where UM(L) is the specification of a universal machine programmable in language L and X the specification of the program in its memory we need.

The denotational semantics sem(L) of a language L defines for each program P in L a predicate sem(L)(P), usually a huge conjunction.

A universal machine "executes" programs written in its language, provided these are loaded into its memory. So UM(L) is defined as follows:

UM(L) := ∀P. load(P)⇒sem(L)(P)

Obviously, our X must be:

∃P. load(P)∧(sem(L)(P)⇒S)

The complete correctness theorem

(∀P. load(P)⇒sem(L)(P)) ∧ (∃P. load(P)∧(sem(L)(P)⇒S)) ⇒ S

than reads: "A universal L-machine with loaded in its memory some program P, the semantics of which implies specification S, is an implementation of S."

If we want to consider the programming language L as a blueprint language we must define which specifications are satisfied by an arbitrary program P. But that is easy: the realisation of a blueprint P consists of P loaded into the computer:

P sat load(P)

If we can prove for some specific program P' that

sem(L)(P')⇒S

we can conclude that

P' sat load(P')∧(sem(L)(P')⇒S)

from which follows that P' satisfies our X.

Software engineers find it self-understanding that programs are loaded into a computer, which always is assumed to be available. When they say "P' satisfies S" they mean:

(sem(L)(P')⇒S) ∧ UM(L) ∧ load(P')