TiML: a functional language for practical complexity analysis with invariants

We present TiML (Timed ML), an ML-like functional language with time-complexity annotations in types. It uses indexed types to express sizes of data structures and upper bounds on running time of functions; and refinement kinds to constrain these indices, expressing data-structure invariants and pre/post-conditions. Indexed types are flexible enough that TiML avoids a built-in notion of ≴size,≵ and the programmer can choose to index user-defined datatypes in any way that helps her analysis. TiML's distinguishing characteristic is supporting highly automated time-bound verification applicable to data structures with nontrivial invariants. The programmer provides type annotations, and the typechecker generates verification conditions that are discharged by an SMT solver. Type and index inference are supported to lower annotation burden, and, furthermore, big-O complexity can be inferred from recurrences generated during typechecking by a recurrence solver based on heuristic pattern matching (e.g. using the Master Theorem to handle divide-and-conquer-like recurrences). We have evaluated TiML's usability by implementing a broad suite of case-study modules, demonstrating that TiML, though lacking full automation and theoretical completeness, is versatile enough to verify worst-case and/or amortized complexities for algorithms and data structures like classic list operations, merge sort, Dijkstra's shortest-path algorithm, red-black trees, Braun trees, functional queues, and dynamic tables with bounds like m n logn. The learning curve and annotation burden are reasonable, as we argue with empirical results on our case studies. We formalized TiML's type-soundness proof in Coq.

[1]  Chris Okasaki Three Algorithms on Braun Trees , 1997, J. Funct. Program..

[2]  Daniel R. Licata,et al.  Denotational cost semantics for functional languages with inductive types , 2015, ICFP.

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

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

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

[6]  Patrick Maxim Rondon,et al.  Liquid types , 2008, PLDI '08.

[7]  Martin Hofmann,et al.  Amortized Resource Analysis with Polynomial Potential , 2010, ESOP.

[8]  Frank Pfenning,et al.  Eliminating array bound checking through dependent types , 1998, PLDI.

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

[10]  Ralph Benzinger,et al.  Automated complexity analysis of Nuprl extracted programs , 2001, Journal of Functional Programming.

[11]  Ranjit Jhala,et al.  Bounded refinement types , 2015, ICFP.

[12]  Paul C. Kocher,et al.  Timing Attacks on Implementations of Diffie-Hellman, RSA, DSS, and Other Systems , 1996, CRYPTO.

[13]  Elvira Albert,et al.  Live heap space analysis for languages with garbage collection , 2009, ISMM '09.

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

[15]  Jürgen Giesl,et al.  Alternating Runtime and Size Complexity Analysis of Integer Programs , 2014, TACAS.

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

[17]  James D. McCawley,et al.  A Program for Logic , 1972 .

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

[19]  Dan R. Ghica,et al.  Geometry of synthesis III: resource management through type inference , 2011, POPL '11.

[20]  Sumit Gulwani,et al.  SPEED: precise and efficient static estimation of program computational complexity , 2009, POPL '09.

[21]  Ugo Dal Lago,et al.  The geometry of types , 2012, POPL.

[22]  Deepak Garg,et al.  A type theory for incremental computational complexity with control flow changes , 2016, ICFP.

[23]  David K. Gifford,et al.  Static dependent costs for estimating execution time , 1994, LFP '94.

[24]  Bernd Grobauer,et al.  Cost recurrences for DML programs , 2001, ICFP '01.

[25]  Ankush Das,et al.  Towards automatic resource bound analysis for OCaml , 2016, POPL.

[26]  R. Tarjan Amortized Computational Complexity , 1985 .

[27]  Manish Mahajan,et al.  Proof carrying code , 2015 .

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

[29]  Nikolaj Bjørner,et al.  Z3: An Efficient SMT Solver , 2008, TACAS.

[30]  Elvira Albert,et al.  COSTA: Design and Implementation of a Cost and Termination Analyzer for Java Bytecode , 2008, FMCO.

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

[32]  Juan Chen,et al.  Verifying higher-order programs with the dijkstra monad , 2013, PLDI.

[33]  Elvira Albert,et al.  Automatic Inference of Upper Bounds for Recurrence Relations in Cost Analysis , 2008, SAS.

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

[35]  Martin Hofmann,et al.  A program logic for resources , 2007, Theor. Comput. Sci..

[36]  Ralph Benzinger,et al.  Automated higher-order complexity analysis , 2004, Theor. Comput. Sci..

[37]  Sumit Gulwani,et al.  The reachability-bound problem , 2010, PLDI '10.

[38]  Robert Harper,et al.  Structure and Efficiency of Computer Programs , 2014 .

[39]  Elvira Albert,et al.  Cost Analysis of Java Bytecode , 2007, ESOP.

[40]  Sumit Gulwani,et al.  A Numerical Abstract Domain Based on Expression Abstraction and Max Operator with Application in Timing Analysis , 2008, CAV.

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

[42]  William R. Harris,et al.  Complexity verification using guided theorem enumeration , 2017, POPL.

[43]  Viktor Kuncak,et al.  Symbolic Resource Bound Inference for Functional Programs , 2014, CAV.

[44]  Xin-She Yang,et al.  Introduction to Algorithms , 2021, Nature-Inspired Optimization Algorithms.

[45]  Dan S. Wallach,et al.  Denial of Service via Algorithmic Complexity Attacks , 2003, USENIX Security Symposium.

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

[47]  Arthur Charguéraud,et al.  Machine-Checked Verification of the Correctness and Amortized Complexity of an Efficient Union-Find Implementation , 2015, ITP.

[48]  Ugo Dal Lago,et al.  Analysing the complexity of functional programs: higher-order meets first-order , 2015, ICFP.

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

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

[51]  Ronald L. Rivest,et al.  Introduction to Algorithms, third edition , 2009 .

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

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

[54]  Georg Moser,et al.  The Complexity of Interaction (Long Version) , 2015, ArXiv.

[55]  Umut A. Acar,et al.  Refinement Types for Incremental Computational Complexity , 2015, ESOP.

[56]  Georg Moser,et al.  The complexity of interaction , 2016, POPL.