Liquidate your assets: reasoning about resource usage in liquid Haskell

Liquid Haskell is an extension to the type system of Haskell that supports formal reasoning about program correctness by encoding logical properties as refinement types. In this article, we show how Liquid Haskell can also be used to reason about program efficiency in the same setting. We use the system's existing verification machinery to ensure that the results of our cost analysis are valid, together with custom invariants for particular program contexts to ensure that the results of our analysis are precise. To illustrate our approach, we analyse the efficiency of a wide range of popular data structures and algorithms, and in doing so, explore various notions of resource usage. Our experience is that reasoning about efficiency in Liquid Haskell is often just as simple as reasoning about correctness, and that the two can naturally be combined.

[1]  Robert Atkey,et al.  Amortised Resource Analysis with Separation Logic , 2010, ESOP.

[2]  Frank Pfenning,et al.  Dependent types in practical programming , 1999, POPL '99.

[3]  John Darlington,et al.  A Transformation System for Developing Recursive Programs , 1977, J. ACM.

[4]  Martin Hofmann,et al.  Static prediction of heap space usage for first-order functional programs , 2003, POPL '03.

[5]  Andrew Moran,et al.  Improvement in a lazy context: an operational theory for call-by-need , 1999, POPL '99.

[6]  Ulf Norell,et al.  Dependently typed programming in Agda , 2009, TLDI '09.

[7]  Robert Bruce Findler,et al.  A Coq Library for Internal Verification of Running-Times , 2016, FLOPS.

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

[9]  Pedro B. Vasconcelos Space cost analysis using sized types , 2008 .

[10]  Steffen Jost,et al.  Type-Based Cost Analysis for Lazy Functional Languages , 2017, Journal of Automated Reasoning.

[11]  Peng Wang,et al.  TiML: a functional language for practical complexity analysis with invariants , 2017, Proc. ACM Program. Lang..

[12]  David Sands,et al.  Total correctness by local improvement in program transformation , 1995, POPL '95.

[13]  Martin Hofmann,et al.  Multivariate amortized resource analysis , 2012, TOPL.

[14]  Nils Anders Danielsson Lightweight semiformal time complexity analysis for purely functional data structures , 2008, POPL '08.

[15]  Chris Okasaki,et al.  Purely functional data structures , 1998 .

[16]  Gilles Barthe,et al.  Monadic refinements for relational cost analysis , 2017, Proc. ACM Program. Lang..

[17]  Gilles Barthe,et al.  Bidirectional type checking for relational properties , 2018, PLDI.

[18]  Karl Crary,et al.  Resource bound certification , 2000, POPL '00.

[19]  Zhong Shao,et al.  Automatic Static Cost Analysis for Parallel Programs , 2015, ESOP.

[20]  Kevin Hammond,et al.  Inferring Cost Equations for Recursive, Polymorphic and Higher-Order Functional Programs , 2003, IFL.

[21]  Amr Sabry,et al.  Proving the correctness of reactive systems using sized types , 1996, POPL '96.

[22]  Shan Lu,et al.  Understanding and detecting real-world performance bugs , 2012, PLDI.

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

[24]  Graham Hutton,et al.  Functional Pearl: Theorem Proving for All (Equational Reasoning in Liquid Haskell) , 2018, ArXiv.

[25]  Marco Gaboardi,et al.  Relational cost analysis , 2017, POPL.

[26]  Martin Hofmann,et al.  Multivariate amortized resource analysis , 2011, POPL '11.

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

[28]  Martin Hofmann,et al.  Resource Aware ML , 2012, CAV.

[29]  Martin Hofmann,et al.  Static determination of quantitative resource usage for higher-order programs , 2010, POPL '10.

[30]  Viktor Kuncak,et al.  Contract-based resource verification for higher-order functions with memoization , 2017, POPL.

[31]  Ranjit Jhala,et al.  Abstract Refinement Types , 2013, ESOP.