Formal Methods of Software Design: an online course by Eric Hehner
cs.toronto.edu
cs.toronto.edu
That said, I wish courses like this would stop using terms like "software design" or "software construction" in their descriptions. This course hardly seems to step out of the realm of algorithms.
This has absolutely nothing to do with software design, unless your program has 300 LOC in total. Software design is much more a social science than most CS researchers dare to admit, so they just keep refining their techniques of dealing with advanced but finegrained things that few programmers do a lot (such as algorithms).
[1] http://cava.in.tum.de/templates/publications/CAV2013.pdf
I have mixed feelings about Coq as a tool for software design. On the one hand I think it's feasible to use Coq to prove correctness properties of your programs. On the other hand I feel it can sometimes be extremely tedious and / or difficult to show some properties. I do believe it is the future to prove properties about parts of your program, though.
Lately I have been working on brainfuck in Coq[bf] in my spare time. I have spent almost two weeks on the project now and I have been able to show that 1) the "Hello World!" program on brainfuck's wikipedia page does indeed output "Hello World!"[hello], and 2) the correctness of a simple compiler from arithmetic expressions (with +, -, and *) to brainfuck[compiler]. The project is more than 1000 lines of code. I must admit some of the code / proofs are messy and could probably be shorter, but I think it does indicate how much work it requires (and how messy brainfuck is!)
[sf]: http://www.cis.upenn.edu/~bcpierce/sf/
[cpdt]: http://adam.chlipala.net/cpdt/
[bf]: https://github.com/reynir/Brainfuck
[hello]: https://github.com/reynir/Brainfuck/blob/master/bf_theorems....
[compiler]: https://github.com/reynir/Brainfuck/blob/master/ae_compiler....
Edit: I just remembered this talk by Wouter Swierstra where he proves some correctness properties for the core of xmonad: http://www.youtube.com/watch?v=jqaOU8kqykg (unfortunately I can't find the slides at the moment).
For all its simplicity, the theory is still general: it deals with parallel, sequential, probabilistic, deterministic, standalone, and interactive programs, as well as time (incl. real-time) and space bounds. It can even be used as a rigorous way to solve probability problems by hand, by writing a program to simulate the scenario and proving what its result is. (http://www.cs.toronto.edu/~hehner/ProPer.pdf)
As someone who's gotten by quite well with thinking about boolean logic as just true and false, the first two videos have absolutely blown my mind.