Theorem proving for all: equational reasoning in liquid Haskell (functional pearl)

Equational reasoning is one of the key features of pure functional languages such as Haskell. To date, however, such reasoning always took place externally to Haskell, either manually on paper, or mechanised in a theorem prover. This article shows how equational reasoning can be performed directly and seamlessly within Haskell itself, and be checked using Liquid Haskell. In particular, language learners --- to whom external theorem provers are out of reach --- can benefit from having their proofs mechanically checked. Concretely, we show how the equational proofs and derivations from Graham's textbook can be recast as proofs in Haskell (spoiler: they look essentially the same).

[1]  Clark W. Barrett,et al.  The SMT-LIB Standard Version 2.0 , 2010 .

[2]  Graham Hutton,et al.  Calculating correct compilers , 2015, Journal of Functional Programming.

[3]  J. McKinna FUNCTIONAL PEARL A type-correct , stack-safe , provably correct expression compiler in Epigram , 2006 .

[4]  Richard A. Eisenberg,et al.  Dependent Types in Haskell: Theory and Practice , 2016, ArXiv.

[5]  Joachim Breitner A promise checked is a promise kept: inspection testing , 2018, Haskell@ICFP.

[6]  Frank Pfenning,et al.  Refinement types for ML , 1991, PLDI '91.

[7]  Stephanie Weirich,et al.  Total Haskell is reasonable Coq , 2017, CPP.

[8]  Niki Vazou,et al.  Liquid Haskell: Haskell as a Theorem Prover , 2016 .

[9]  Yves Bertot,et al.  Interactive Theorem Proving and Program Development: Coq'Art The Calculus of Inductive Constructions , 2010 .

[10]  Sophia Drossopoulou,et al.  Zeno: An Automated Prover for Properties of Recursive Data Structures , 2012, TACAS.

[11]  Tobias Nipkow,et al.  Structured Proofs in Isar/HOL , 2002, TYPES.

[12]  Richard S. Bird,et al.  An introduction to the theory of lists , 1987 .

[13]  Lawrence Charles Paulson,et al.  Isabelle/HOL: A Proof Assistant for Higher-Order Logic , 2002 .

[14]  Graham Hutton,et al.  Programming in Haskell , 2007 .

[15]  K. Rustan M. Leino,et al.  Verified Calculations , 2013, VSTTE.

[16]  Leonidas Lampropoulos,et al.  A tale of two provers: verifying monoidal string matching in liquid Haskell and Coq , 2017, Haskell.

[17]  U. Norell,et al.  Towards a practical programming language based on dependent type theory , 2007 .

[18]  Andy Gill,et al.  Reasoning with the HERMIT: tool support for equational reasoning on GHC core programs , 2015, Haskell.

[19]  Richard S. Bird,et al.  Pearls of Functional Algorithm Design , 2010 .

[20]  Florian Haftmann,et al.  From higher-order logic to Haskell: there and back again , 2010, PEPM '10.

[21]  Philip Wadler,et al.  Refinement reflection: complete verification with SMT , 2017, Proc. ACM Program. Lang..

[22]  K. Rustan M. Leino,et al.  Trigger Selection Strategies to Stabilize Program Verifiers , 2016, CAV.

[23]  K. Rustan M. Leino,et al.  Dafny: An Automatic Program Verifier for Functional Correctness , 2010, LPAR.

[24]  Pierre-Yves Strub,et al.  Dependent types and multi-monadic effects in F* , 2016, POPL.

[25]  Edwin Brady,et al.  Idris, a general-purpose dependently typed programming language: Design and implementation , 2013, Journal of Functional Programming.

[26]  Simon L. Peyton Jones,et al.  HALO: haskell to logic through denotational semantics , 2013, POPL.

[27]  Ranjit Jhala,et al.  Refinement types for Haskell , 2014, ICFP.

[28]  Jeremy Avigad,et al.  The Lean Theorem Prover (System Description) , 2015, CADE.