A Liveness Example in TLA+
surfingcomplexity.blog
surfingcomplexity.blog
However, there are ways to create formal ties between a TLA+ spec and a running program. As always, the sounder the method the more costly it is (and the cost often grows faster than the increased confidence). One approach that is being research is checking execution logs against the model, perhaps online as the program is running.
At the end of this talk, https://youtu.be/TP3SY0EUV2A, I mention the technique and theory behind it, referring to this paper, Model-Based Trace-Checking [1]. I believe research is ongoing and you can find more recent papers on the subject.
Practices that are not usually considered formal methods include clever semi-blackbox fuzzing (like Antithesis) and mutation testing to improve test quality.
But this exact problem is why I am more interested in approaches that integrate specification and implementation into a single (dialectical) process (e.g., via type-theoretic methods).
I have no idea how well it works, but it seems pretty interesting.
I do think that that's something a bit more compelling about something like Isabelle, which offers first-class support for exporting programs that can be directly executed, which in theory would inherit all the proofs for the parent Isabelle (though that's not strictly true).
Some work to look at, if you are curious: Event-B, Trillium, IronFleet
Someone else reads both and tries to reason about the proof and theorem and notifies the creator of there are mismatches.
A more practical person goes and translates all that math/theory to code.
Another practical person will check implementation and theory and notify the implementor of mismatches.
TLA+ is basically an automated version of step two in this process. Someone has an idea for a theorem, writes it down in TLA+ and the system will notifyil if it makes any sense.