  SMT-based verifiers have long been an effective means of ensuring safety
properties of programs. While these techniques are well understood, we show
that they implicitly require eager semantics; directly applying them to a lazy
language is unsound due to the presence of divergent sub-computations. We
recover soundness by composing the safety analysis with a termination analysis.
Of course, termination is itself a challenging problem, but we show how the
safety analysis can be used to ensure termination, thereby bootstrapping
soundness for the entire system. Thus, while safety invariants have long been
required to prove termination, we show how termination proofs can be to soundly
establish safety. We have implemented our approach in liquidHaskell, a
Refinement Type-based verifier for Haskell. We demonstrate its effectiveness
via an experimental evaluation using liquidHaskell to verify safety, functional
correctness and termination properties of real-world Haskell libraries,
totaling over 10,000 lines of code.
