HN Debrief

The Case Against Formal Verification, 50 Years Later

  • Programming
  • Developer Tools
  • AI
  • Infrastructure
  • Security

The post is a 50-years-later response to the DeMillo, Lipton, and Perlis critique of formal verification. It argues that the old paper was right about one thing in particular: verification is not just math, it is also a social process of agreeing on abstractions, requirements, and acceptable proof artifacts. But the stronger historical claim, that formal verification is fundamentally mismatched to real software and unlikely to scale, looks much weaker now that theorem provers, model checkers, SAT and SMT techniques, and compute have improved so much.

Treat formal verification as a targeted engineering tool, not an all-or-nothing philosophy. If you run critical infrastructure, compilers, distributed systems, or policy engines, the practical move is to verify specific properties with clear specs and pick tooling that reduces the spec-to-code gap.

Discussion mood

Cautiously positive. Most comments rejected the old blanket case against formal verification, but they were unsentimental about where it breaks down: bad specs, the gap between models and production code, steep learning curves, and the fact that many products do not have one clean thing to prove.

Key insights

  1. 01

    CompCert's record against random testing

    CompCert matters because it turns the argument from theory into defect data. The claim here is specific: Csmith found no wrong-code bugs in CompCert's formally verified core, while other C compilers did fail that test. That sharpens what verification bought. It did not guarantee the compiler would never crash or reject input, but it did fence off a class of miscompilation bugs that high-volume testing kept exposing elsewhere.

    If you care about a narrow failure mode that testing misses repeatedly, define that property precisely and verify that slice. You do not need a proof of the whole system to get a step-change in reliability.

      Attribution:
    • pfdietz #1
  2. 02

    Tooling only pays when proofs touch code

    The practical dividing line is whether the proof lives next to the implementation or floats above it as architecture documentation. SPARK, hardware property languages in SystemVerilog, and research that carries semantics through compilation all attack the same problem: a proof of a separate model does not secure the shipped binary. This shifts the evaluation criterion for tools. Expressiveness matters, but direct linkage between spec, code, and generated artifacts matters more.

    When choosing a formal methods stack, ask first how it closes the path from proved artifact to deployed artifact. If that story is weak, budget for verification as design validation, not implementation assurance.

      Attribution:
    • JCattheATM #1
    • ajdude #1
    • y1n0 #1
    • black_knight #1
    • rrook #1
  3. 03

    Lean is emerging as a systems tool

    Lean showed up here less as a theorem prover for pure math and more as a way to build constrained system components. The workflow engine example, plus the Cedar mention, points to a pattern: use dependent types and rich data modeling to make invalid states impossible inside the core logic, then interoperate with C or other runtimes at the boundary. That is a different pitch from proving every line correct. It is about using the type system and proof machinery to harden the parts where business rules and state transitions usually rot.

    For policy engines, workflow systems, and other rule-heavy components, look at proof-oriented languages as a way to encode invariants into the core model. You can keep the verified kernel small and push messy integration code to the edges.

      Attribution:
    • ibarrajo #1
    • nylonstrung #1 #2
  4. 04

    Most value comes before the final proof

    The strongest benefit is often architectural discipline, not the proof artifact you print at the end. Once you try to verify something, you are forced to define invariants, expose edge cases, and separate the parts with clean semantics from the parts that are too messy. That is why partial verification is not a cop-out. Proving properties like idempotence, memory safety, liveness, or fault handling on selected components can improve system design even when the full product remains impossible to specify cleanly.

    Use verification pressure as a design tool early in architecture work. Pick a handful of invariants that would meaningfully reduce outages, data loss, or security failures, and restructure code until those are tractable to prove.

      Attribution:
    • AlotOfReading #1
    • gr_norm #1 #2
    • ip26 #1
  5. 05

    Economics decide where rigor shows up

    Hardware and safety-critical software already absorb far more verification effort because patching failures is expensive or impossible. That framing cuts through a lot of ideology. Teams do not avoid rigor because they hate correctness. They avoid it when market pressure rewards speed over assurance and post-release fixes are cheap. Where failure is catastrophic, the staffing model flips and verification becomes routine engineering overhead.

    Do not ask whether formal verification is universally worth it. Ask what a latent defect costs in your domain, and staff your assurance process accordingly.

      Attribution:
    • artemonster #1 #2
    • david-gpu #1
    • ncruces #1

Against the grain

  1. 01

    AI help may not broaden adoption

    Current AI gains mostly seem to accrue to people who already know how to frame formal methods problems. The hard part is still picking the right abstraction and writing correctness properties that are both meaningful and tractable. If AI eventually gets good enough to handle that art reliably for non-experts, it is not obvious the impact stops at verification rather than swallowing larger chunks of software design and even product definition.

    Do not build a tooling roadmap around the assumption that AI will soon make formal methods accessible without in-house expertise. Hire or train people who can judge specs and properties now, then use AI as leverage on top.

      Attribution:
    • pron #1
  2. 02

    Declarative constraints may beat full proofs

    For many teams using AI to produce software artifacts, tightening the output space with schemas, manifests, and policy languages may be the higher-return move than jumping to full formal verification. That keeps agents inside bounded, lintable structures and avoids pretending you have end-to-end rigor when the real system still depends on humans trusting a long chain of tools and generated artifacts. It is a less ambitious approach, but often a more honest one.

    If your immediate problem is controlling AI-generated code or config, start by forcing outputs into constrained declarative forms. Move to theorem proving only when you have a stable core with properties worth proving.

      Attribution:
    • perching_aix #1 #2

In plain english

Cedar
A policy language and authorization system that uses formal methods to ensure the policy engine behaves correctly.
CompCert
A C compiler whose core correctness properties were formally proved, especially that compilation preserves program meaning.
Csmith
A tool that generates random C programs to find compiler bugs by stress testing them.
dependent types
Types that can depend on values, which lets programmers encode detailed correctness conditions directly into data structures and functions.
formal verification
A method for mathematically proving that software or hardware meets specific correctness or security properties.
Lean
A proof assistant and programming language used to write mathematics in a formal way that a small trusted kernel can mechanically verify.
liveness
A class of system properties stating that something good eventually happens, such as a request eventually receiving a response.
model-code gap
The mismatch between a formally verified model or specification and the real implementation that actually runs in production.
SMT techniques
Methods that use SMT solvers to reason automatically about program properties and constraints.
Spark
Apache Spark, a distributed data processing engine used for large-scale analytics and data engineering.
spec
A specification document that defines expected behavior, requirements, or constraints for a system.
SystemVerilog
A hardware description and verification language used to design and verify digital circuits.
TLA+
A formal specification language used to model and verify system behavior.

Reference links

Proof assistants and formal methods tools

  • Rocq documentation
    Mentioned as the renamed Coq proof assistant and relevant to code extraction and proof workflows.
  • Specula
    Shared as an example of using LLMs with TLA+ style modeling to derive code or find bugs.
  • Hale language proof page
    Presented as an attempt to bake system modeling and proof into the language itself.
  • Clément Pit-Claudel website
    Offered as a starting point for work on carrying proofs across compilation and narrowing the model-code gap.

Historical and background references

  • Mutation testing
    Linked to explain the older testing approach discussed alongside formal verification.
  • Verifier manual
    Shared as a historical artifact showing an earlier architecture for automated verification.
  • nqthm repository
    Linked as a port of the Boyer-Moore theorem prover mentioned in the historical comment.
  • Rocq renaming discussion
    Referenced in a side discussion about the Coq to Rocq rename.

Specialized application areas