Are You Using Z-Notation to Validate Your Software?
ghopson asks: "Many years ago in the early nineties I became aware of a software definition language called Z, which was based on set theory. The idea was that a software system could be defined in 'Z', and then that system could be mathematically proven to be 100% correct (in other words, zero defects).What is the current state of play with 'zero defect' software development? I know Z still exists, that there is a software development method (the B-method) associated with it. Have techniques and advances such as MDA advanced zero-defect software development? Or would a set of robust unit tests suffice?"
but when I transferred my algorithm into the system I made a small error.
so I designed a system that would convert C code into Z code. unfortunately I never did get around to fully debugging it, so I decided to write a theorem prover that would work on straight C code.
this one worked great, but one day it didn't catch a bug in some code that I *knew* was buggy.
so I decided to write another theorem prover to parse the code of the first one. I figured if I fed the code of each one into the other, that would greatly reduce the chances of error? well, the second one crashed at startup and the first one said it was correct.
turned out to be a bug in the OS. So I fed the OS source code into the first one, and it found some defects. I fixed the defects but then the system wouldn't boot any more. I think it was actually a bug in the C compiler, and I was going to fix it for real this time, but it was getting late.
so I decided to just try to write clear, simple code and fix bugs as they are reported.
As a software developer, I'm not sure what this buys me. I can prove that if my software is a 100% correct implementation of the ideal system decribed in Z, then it's bug-free.
In other words, I can prove that if my software is 100% bug-free, it's bug-free. Woohoo. This doesn't address the case where my program doesn't fully conform to the Z specification, does it?
ZFS: because love is never having to say fsck
This is the 21st century my friend. Products aren't supposed to have a measurable amount of usefulness or quality. They are merely an excuse for other people to get their hands in your pocket.
Through comprehensive hyping and brainwashing (err, marketing) you could get a sizable amount of money out of selling a single turd. Ever heard of Merda d' Artista? It literally translates to "Artist's shit" and it IS shit. Very old shit but nothing more than human faeces. And yet, we are supposed to believe that it is a minimalist protest against the state of art (blah blah monocle polish yacht hampsters).
The thing sold for a bundle.
Perhaps they could include spell checking?
Sig under construction since 1998.
For the practical world, unittests seem to be the way to go. A large number of people have been experiencing very great and real success, without having to themselves be absolute geniuses to use.
Provable programs, on the other hand, are typically so complicated for a real-world program that your provably bug-free program still has bugs, because it turns out your model is wrong, because it was written by a human, not a god.
I'm very unimpressed with the whole "provable program" crowd for any but the most trivial proofs; decades of claims, little to show for it, and all based on the rather wrong idea that if we just push the need for perfection back one level, somehow the computer can magically take up the slack and prevent the bugs from ever existing. The unittesting philosphy, that bugs will happen and it's more important to test and fix them, since complete prevention is impossible anyhow, is much more based in reality, and correspondingly works much better in the real world.
(Provably correct computing is one of those branches of technology that may produce something useful, but is unlikely to ever acheive its stated "ultimate goals"; I class pure q-bit based quantum computing and pure biologically-grown computing in here as well.)
Your question is about Formal Methods. This field in computer science seems more popular in Europe than in the US theese days.
Two good articles you should read :
If your question was about their use in practical projects in industry, I've heard recently of teams doing serious work for Airbus (safety-critical embedded software using either B or Esterel) or for Gemplus (entirely proven JVM for javacards using B).
I vaguely remember that short of an exhaustive date set test, it's actually IMPOSSIBLE to determine mathematically that an algorithm is correct for any but the simplest (read shortest) pieces of code.
ACL2 is a theorem proving and modeling environment, based on Common Lisp, which is used for verification of hardware and software. I believe AMD used it to prove the correctness of the floating-point division algorithm in one of their processors.
Bush Lies Watch
Theoroms work great when the number of variables is finite and limited in scope, but when the variables are huge and multi-dimensional, the problem gets very hard. Not impossible, just too time consuming and likely useless. One could write a theorom general enough to test for 95% of all possible permutations, but that could be huge. Having a more directed set of tests in those types of cases is much more efficient than having a program prove your application is bug free based on a theorom. Writing an elegant theorom in a certain extent requires expert knowledge of the problem domain. If that is the case, then it would still be easier to use unit testing as a way to validate the program. Theorom are great in physics and math, but software engineering has too many variables. Most of the most interesting problems are the result of illogical human behavior or unpredictable conditions.
both robust unit testing and formal methods have their place --- formal methods for proving design and unit testing for proving implementation. however, it seems to me that the question of why formal methods aren't more widespread in the us boils down to a question of perceived cost v. perceived benefit. let's say it takes "n-nines" of reliability to keep enough of your customers satisfied enough to keep coming back to you. let's say you've got two designs for software which accomplishes a certain task, and both models (if implemented correctly) would result in a product that the customer would be sufficiently happy with. which model do you implement? odds are mostly likely that you'll go with the cheapest one, because that's what maximizes profits. (forget everything i just said if you are an academic or coding for the love of it). to borrow a line from an engineering prof: "perfection is the enemy of good enough, and it's good enough that sells"
Doesn't "proving" the perfection of a body of code mathematically sound like it would basically face the same barriers as encountered in the infamous halting problem? That's not to say it can't be done with sufficient resources for a sufficiently simple body of code, but I would think there would be no general solution that always works in reasonable time for validating real code.
11*43+456^2
Some people here don't seem to understand the usefulness of Z.
...
...
:-)= ),
When developing software the process might look something like this:
Specification (created with or by client)
Design
Implementation
Testing
Typically a specification could be a great big document written in english. It could have ambiguities, it could have subtle contradictions, it could be missing vital information.
If the specification is written in Z, then there are tools that let you:
- Find ambiguities or contradictions.
- Prove that some fact of the system necessarily follows from some other fact.
- Prove whether assumptions are correct.
- Test what results are possible given certain inputs and sequences of operations.
There are processes for, step by step, turning a specification into something more like real code, while proving that the two forms mean the same thing (apart from whatever limits are introduced). So, for example the transformed specification might change a variable from being an integer to being an integer in the range 0..65535, and you can test what effects this has.
All of this can be done before writing a single line of actual program.
Yes mistakes are still possible, but if done right, they are significantly less likely; and unlikely to be due to a misunderstanding about the capabilities of some part of the system.
Z can also help in the process of testing an implementation. From the specification you can see that, for example, the number 50 is the input value at which the behaviour of a function significantly changes, so you know to produce test sets checking the input of 50 and values on either side. This doesn't _have_ to be done by hand; my thesis supervisor is part of a project to automatically generate test sets from B and Z specifications.
So creating a Z specification:
-mean more work before coding starts (I think this is what makes most people uncomfortable with it
-forces you to be very specific about what correct behaviour is,
-allows you to test properties of the system before it is created,
-can help to make more useful test sets.
(Disclaimer: My Master's thesis involves making tools for Z, so I could be biased; but it also means I probably know more than average about Z).
bits and peace
Nicholas Daley
I assume this is supposed to be an 'Ask Slashdot' story.
bits and peace
Nicholas Daley
``Beware of bugs in the above code; I have only proved it correct, not tried it.''
Donald E. Knuth
Felipe Hoffa
I vaguely remember that short of an exhaustive date set test, it's actually IMPOSSIBLE to determine mathematically that an algorithm is correct for any but the simplest (read shortest) pieces of code.
/* terminate and return 1 for any positive input */ ... are really, really hard to prove correct. In general, it's not feasible to prove big pieces of practical code correct using techniques like these, but with suitable abstraction it can be a helpful part of the engineering process. In any case, it is definitely not impossible.
This is total crap. You can, of course, prove algorithms of any size correct. Some really long (textually) algorithms can be easy to prove, and some really short ones, like this:
int collatz(int i) {
if (i & 1) return collatz (i * 3 + 1);
else return collatz(i >> 1);
}
language called Z, which was based on set theory.
Relational is also based around set theory. I think relational is cool, especially if done right (the current vendors and languages need help IMO).
Relational could also be made more friendly by creating operators and syntax that people can better relate with. The operators can be defined based on combinations of Dr Codd's original operators, but more "natural".
There does not seem to be a lot of pressure to improve upon relational theory beyond the "Oracle model". Chris Date and a few others are about the only researchers making much effort in this field. But they are not very good at marketing their ideas, so most people get confused and ignore them.
I hope that relational gets a "boom" of fresh attention the way that OO did. Of course, some people get carried away during such booms, and create some silly tools or languages.
Table-ized A.I.
adjust your monocle polish jokes accordingly.
In IBM mainframe land, there's a program called IEFBR14 designed to do nothing (don't ask, you DON'T want to know).
The usual story is that the first version had a bug report filed because, although it did indeed return, it didn't set the exit code.
Next, according to the conventional version, the linkage editor gagged because the source ended with an END directive instead of END IEFBR14.
With that fixed, the next bug report was that it didn't interoperate properly with the dump tools, in that it didn't stick the program name into a predictable area of the code.
Then came the bug report about chaining register save areas (again, you don't want to know -- it's related to the fact that the machines didn't have a stack).
Nor was that the end of it, a later bug report was that it wasn't being flagged as reentrant when it got linked.
That's five bug reports against a null program. All of them were integration problems and/or omissions in the specification.
There's a class of bugs formal methods can help with, but that class is a minority in most commercial work.
I attended Aston University in the UK [ www.cs.aston.ac.uk ] and they are still providing a final year module 'Formal Software Development' based around the Z language.
Perhaps this has something to do with the fact that the final year senior tutor has written a book on it - but that doesn't make it any less (or more) useful.
see:b usinternet.php?inputmod=CS3120
http://www.cs.aston.ac.uk/phpmodules/displaysylla
for the lowdown. So in answer to your question - yes people are still using it, at least academically.
cheers,
olly.
I studied for my CS degree at the University of York in the early 90's, who - at the time - were really pushing Z and Ada as the stuff of the future. One thing that stood out from the formal specification course, at least in my mind, was the example Z specification for a function to swap the values of two variables. Basically :
:
swap(a,b)
tmp = a
a = b
b = tmp
The pseudocode is simple enough, but the Z spec took up a whole page. This put people off - if the smallest function in a minor subsystem of an application takes a whole page and much head-scratching to figure out, how long will the rest of the software take? Surely it's so time consuming as to be infeasible for real world use. Hardly any on the course really "got it", and I was one of the many who didn't. A friend of mine went on to use Z in his final year project, and at some point *ting* - he got it and found that it was good. I've never seen or heard of Z being used anywhere since, but some day I want to have another look at my notes and text books to see if it makes any more sense yet, and if so, whether it can help my work.
I don't know if they still advocate Z, but they started teaching Eiffel instead of Ada the year after I left..
Great I just passed an exam in this, but lets see if I still remember it..
First you we have to get the question right - are you talking about validation or verification of software? They are quite different from each other:
The above is a quote of Boehm from 1979 I think... can't remember the exact title.
As you can propably guess there is quite a difference betweem the two. Unit testing is a method for verification, but from your description Z sounds like validation to me.
--- Martin Skøtt aka. Qoumran
I'm not wrong. What the original poster said is that it's impossible to prove anything but the simplest algorithms correct. That's not true at all; people publish papers with complicated algorithms and proofs of their correctness every day. Those proofs of correctness can usually be concretized to the source code level, it's just painful. It is not impossible! (There is no limit to finite state spaces. Haven't you ever heard of induction??)
I'm not talking about a computer program that examines raw source code and tells you wether it is correct or not, so your other "proof" doesn't apply. I'm not talking about model checking (that's what you seem to describe above), which can be useful, but not usually for *algorithm* analysis. I'm talking about writing down a proof of correctness, and perhaps checking that proof with a computer.
I happen to think these kinds of methods are not practical today (though they can lead to type systems that are practical). But there is certainly no theorem telling us that it's hopeless.
Unless there's been some radical change in the state of the art that I've missed hearing about in the last few years, there's a big problem with Z notation and other methods of forming provably correct programs.
Said killer problem is that all the popular programming languages have features which make it impossible to model them using denotational semantics--that is, to produce mathematical functions which represent the program behavior. For instance, no C-based language can be modeled.
That's not to say that denotational semantics is completely useless. It's used in certain narrow domains, such as hardware--there are numerous chip designs where the circuitry and microcode is proven correct.
However, there's no way you're going to see --check-correctness flags on gcc or javac any time soon.
Of course, the bigger problem with mathematical techniques for proving correctness is that there's no measurable market demand for bug-free software (outside of the few narrow fields alluded to above), and hence no money available to spend on paying highly skilled computer scientists to spend a long time developing provably correct software using obscure programming languages. Instead, everyone just hacks together some alpha-quality code using C++ and calls it version 1.0.
GCHQ Quantum Insert installed. If only our tongues were made of glass, how much more careful we would be when we speak
The idea was that a software system could be defined in 'Z', and then that system could be mathematically proven to be 100% correct (in other words, zero defects).
I've heard of a different idea. Once you define the problem in this language called "C", the software is automatically written by this device called a "compiler", and it is already proven to be 100% correct.
I thought that the most likely cause of software bugs was incorrect specifications. In other words, the code is bug-free and does exactly what you want it to do... but what you want it to do is wrong.
I can't see how a formal system like Z could possibly look past the specification and deduce what you actually intended.
Bart Massey and Jamey Sharp of Portland State have written XCB, a reimplementation of Xlib with an eye towards improved tunability (and an improved API). They were having problems coming up with an implementation that worked properly; the multi-threaded connection handling code was up to four designs and two implementations, all of them incorrect.
- zxcb.pdf
Massey and Robert Bauer of Rational ended up writing a Z specification for that portion of the code, and proved it correct. The C implementation of the spec is in the XCB distribution right now.
Massey and Bauer published a paper describing this effort for USENIX 2002. They conclude with the comment "[t]he sort of lightweight modeling described [above], that isolates a troublesome portion of the system for more detailed study, is especially appropriate[...]".
XCB Wiki: http://xcb.wiki.cs.pdx.edu/
XCB/Z Paper: http://xcb.wiki.cs.pdx.edu/pub/XCB/WebHome/usenix
I finished a class recently that concentrated on using Z for formal modeling. The two professors published a reasonably interesting paper (for Z) on a thread safe X Windows C library binding to the X protocol.
X meets Z: Verifying correctness in the presence of POSIX Threads
Yes, there is. Rice's theorem proves it impossible in the general case.
You are misapplying the theorem, or else don't understand what it says. There are systems where given a program, and a proof, verification of non-trivial properties (like termination) is decidable. Yes, there is no program that will generate that proof for you for arbitrary programs and properties. But that does not mean that a human (or even, sometimes, a computer) can't create a proof for a specific program and then verify that proof mechanically. People do that every day, and it does not mean that the properties are trivial, either in the Rice sense or the practical sense.
The argument you're making is essentially identical to, "The undecidability of the halting problem tells us that writing programs is hopeless." Making general program-writing tools (input spec, output program) is hopeless, yes, but that does not mean that we can't make lots of useful specific programs.
I'd go on, but this is already below the front page fold by five or ten pages, so who'd read it anyway?
I will.
It builds. Ship it!
That's "Mr. Soulless Automaton" to you, Bub.
The Z homepage is a frigging disaster.
What, pray tell, does Z code look like?
In the short term I'm not persuaded by the case for widespread application of formal methods, but in the long run I think it will become very important. Two areas I think are areas that I think are most beneficial for formal methods: firstly verified implementations of network protocols, and journalling file systems.
It's usually quite a few orders of magnitude easier to write correct yet slow code than it is to write correct and optimized code.
I don't mean to be glib by making such a statement as "software is still voodoo", but after reading this thread, it is quite obvious I think that clear understanding of our art is achieved by far too few practitioners, and that is the crux of the problem of software quality.
While provably correct solutions are presently unrealistic, we have myriads of tools to assist in the process of creating high quality software. Specification tools like Z, modelling languages, coverage analysis and profiling software, unit testing and regression prevention methodologies, runtime assertions---all are proven to increase and control quality. Moreover, language constructs such as taxonomic class hierarchies with crisp declarations can prevent many logical or semantic flaws at compile time, but only if used by class designers who understand good architecture and the importance of minimizing conceptual baggage and side-effects.
Yet, I live in a world where I regularly encounter professional developers who do not use version control and move from idea to implementation quickly without adequate (or sometimes without any) specificiations at all. These are not amateur hackers, but well-paid professionals who happen to be working on websites which accept credit cards and banking details, among others.
While many of us can understand and use quality-assurance tools and processes, there are just as many (perhaps more) that rely solely on their intuitive ability to "sling code", and worse, are arrogant in their belief that time spent in formal specification and analysis is a waste of time.
Arguing that particular specification tools are useful is fine, but don't entertain for a moment the belief that the larger problem of software quality is even vaguely related to a lack of theoretical foundation for quality. The theoretical foundation is alive, well, and rich with solutions.
The problem is people, education, and professional standards.
Until there are employment and "best practice" requirements for software engineers which are as rigorous and well-accepted as those for other engineering disciplines, we will continue to unacceptably low quality in the software we use, with an incredible corresponding waste in time and human effort.
No.
Z is a way of formally specifying requirements.
When you are developing a system and you are doing analysis of the the system's requirements given, Z allows you to capture a specification of the requirements in a precise manner.
This is the pretty much the bounds of what Z does.
So
It doesn't prevent programming errors.
It doesn't prevent poor analysis.
It does help getting a requirement of a system that is being devloped down in a precise way.
It acts as an abstration of the system(or model of the system).
It is a good reference for a requirement latter on.
And particularly, it allows a requirement to be verified in the early stages of a SDLC, when it is cheaper to change, rather than when it becomes expensive and unwieldly to do so.
I used Z to design the control software for a radiation therapy machine.
I expressed the safety requirements in Z, and also expressed the detailed design in Z, and argued (I wouldn't say "proved") that the design didn't violate the safety requirements.
We coded the control program in C from the detailed design in Z. Of course we tested the program thoroughly too - you still have to do all that, of course.
The machine has been in use treating patients since July 1999. We haven't killed anyone yet (unlike some other products in this category).
There are some papers and reports about the project at
http://staff.washington.edu/~jon/cnts/index.html
There is a short (3-page) report about our use of Z in this project at
http://staff.washington.edu/~jon/cnts/iccr.html
There is a longer report about the whole project at
http://staff.washington.edu/~jon/cnts/cnts-report. html
The Z for the radiation therapy machine itself is at
http://staff.washington.edu/~jon/z/machine.html
This is a slight variation of the 'halting' problem. :)
This flies in the face of science.
Ok, so your software will work to the design, but who's going to design perfect software?
thank God the internet isn't a human right.
If you allow for an "I don't know" reply, then you can write such an algorithm. The problem is then reduced to one of coding practice, i.e. writing code which the automatic verifier is able to verify.
Z doesn't have to prove all programs (including the one you describe) correct in order to be useful. It only has to prove my program correct to be useful to me.
Patrick Doyle
I mod down every jackass who puts his moderation policy in his sig. Oh, wait a sec....
Incidentally, the halting problem is decidable when memory is finite. Either the program halts or it eventually repeats a previous state. This is not enormously useful, because you can write a program with a huge state space, but it answers the formal objection.
No, he did not shoot down your statement that you "vaguely remember that [such-and-such]".
... right? So the "crap" was in no way directed at you.
Suppose (1) I vaguely recall that in 1996 Joe proved the halting problem was solvable, and (2)Sue is familiar with the "proof" and knows it to be bogus, and (3) she says "this is crap".
Since I admitted my recollection was vague, she is not likely denigrating my powers of recall. And my admitting my recollection was vague, I am clearly not defending Joe's thesis, but raising it speculatively. I am not actually asserting the thesis, so there is no assertion on my part to denigrate. So what does Sue's "this" refer to? Presumeably the thesis itself.
So I think Tom7 was saying that the "[such-and-such]" was crap. You were not standing by the such-and-such, but essentially saying that you *thought* such-and-such was shown
At least, this is how I parse it!
Say the system you want to test has an "input space" (all combinations of possible input parameters) and some output ( a program that doesn't do anything , produce something or has a side effect, is useless). Unit testing is all about defining a series of a "test cases". In each test case we
Writing a new test case is only usefull when it verifies another "behaviour" of the system. Take a look at the way XP approaches testing:
If you look at this procedure in a more abstract way you could say that intuitively you are "partitioning" the input space of the method, where in each partition the system has a different behaviour, described by the representative testcase. So a test case is a representative of a whole class of uses of the system where the system has similar behaviour.
A word on my experience with formal methods : When I started writing unit tests, I noticed some similarities with notions of formal methods I encountered at university:
A similar approach is "stepwise refinement" or "transformation". In this case a method is first entirely formally described, but without an explicit algorithm. The formal description is then step by step transformed into an executable algorithm. Each step is "verifiable", i.e. preserves ths semantics of the formal specification.
The similarities are only vague: hoare calculus verifies a method, but the partitioning is oriented on the program structure, not on the input cases. ADT's do not specify a single method, but a whole class, but the similarity is that there is a process of "finding the right amount of specification".
Both formal and unit testing have their own strenghts and weaknesses:
Formal verification
I looked at Z for a while, but I had a problem with how closely it resembled mathematics. I thought about the momement when I would present a Z specification to a typical client and could not imagine them using it. I would think that they would always go for the text description.
After all, it's the end user who is supposed to approve what you are doing and the typical user is probably someone who avoided algebra in high-school at all costs. Their eyes would glaze over at any mathematics at all. Only the programmers would use it.
Of course I supposed that the text could be could be generated from the Z - but how clean would that look?
Zero defect development is tough to introduce to a development environment because it is so different from what we accept as development. I'm going to make distinctions here between Z, a formal specification, and 'zero defect' development which I believe the author is referring to 'clean room development' Using a formal specification, like Z, a specification can be written for a programming that can be proven to be correct. It's difficult to define 'correct' but essentially the program can be shown not to have any errors of design. With a form specification, the specification of requirments is the design. Following this, formal methods can be iterativley applied to the specification to gradually develop the desired code. At each stage proofs can be offered to show that the code written conforms to the prevous specification + code. When this is done in a clean room environment. The produced code is transfered to a second team who does all the testing. Any fault that is found is considered a fualt of the PROCESS. The code is THROWN AWAY and new code developed from the specification. A recent use of this technique on a large commercial package resulted in just 173 faults being found. ONLY 3 of these were found after release. The biggest problems with these techniques are: 1- Formal specifications are too hard for clients to understand 2- Formal techniques are difficult to learn and use with LOTS of training 3- Throwing away instead of fixing is difficult to comprehend 4- Not all things being developed can be expressed with formal languages. Client Server architectures are very difficult. Especially if they are asynchronous.
You can get a book about Z here.
So why write a Z description if you have UML going on and verticalizing nicely? Does it help increase the speed of reading the comprehensive Russel Logic? Are there PalmPilot tools or something? :_)