You can't find any books by Tony Hoare? See if you can get your hands on:
Hoare, CAR. (Charles Antony Richard), 1934-
Essays in computing science / CAR. Hoare ; C.B. Jones (editor).
Prentice Hall International series in computer science
New York ; London : Prentice Hall, 1989.
ISBN 0132840278 :
Physical details xii,412p : ill. ; 25 cm.
Bibliography: p393-397. - List of works by CAR. Hoare: p398-404. - Includes index.
It includes a reprint of the article about correctness.
A substitution S can require a precondition P to produce a result (or postcondition) Q. So, in your example, the substitution is supposed to establish the result/postcondition Q and Q is
(x == n!). So you can work back from Q
via S to work out what P is. You have actually got the mathematically correct value, but if you are using
Java int arithmetic, you would actually want
(n <= 12 && n >= 0). If you try to calculate 13! you overflow the limits of
int arithmetic.
You now can write a Hoare triplet P[S]Q which means if P is true, then S will establish Q.
There are various ways you can implement this. The simplest is
This is a plain simple precondition, which is stated; if the precondition is not fulfilled then the program is under no obligation to supply the correct answer, not even under any obligation to terminate or provide a result at all.
The next way up is rather more assertive, and even less friendly to the user.
This is equivalent to saying, "
if you get it wrong I shall mess up your program by going into an infinite loop." This is permissible under the strict rules of engagement: no precondition no result.
Even more assertive, and what most people would regard as good programming practice, is to strengthen the precondition into a guard. My previous example was a bit like that, but this next example is easier to use because it returns what is obviously an impossible result. I wouldn't use this myself, but let's see what it does.
That requires the user to check for an incorrect and impossible return value. As I said you are using the precondition as a guard, which can be written G---->[S]Q. If the guard is not fulfilled S never runs at all.
This last method, which is what I
would use, looks like this
This makes it clear to the user that S has never run at all. If there is a wrong argument, then either the user has to catch the Exception, or the application [more precisely the
thread] will stop.
This is a very assertive guard, which builds on and enforces the precondition, and ensures that only correct values are returned.
I shall write about your postcondition very soon.