HASKELL TO LOGIC THROUGH DENOTATIONAL SEMANTICS Dimitrios Vytiniotis, Koen Claessen, Simon Peyton Jones, Dan Rosén POPL 2013, January 2013 1

Download HASKELL TO LOGIC THROUGH DENOTATIONAL SEMANTICS Dimitrios Vytiniotis, Koen Claessen, Simon Peyton Jones, Dan Rosén POPL 2013, January 2013 1

Post on 29-Mar-2015




1 download

Embed Size (px)


<ul><li>Slide 1</li></ul> <p>HASKELL TO LOGIC THROUGH DENOTATIONAL SEMANTICS Dimitrios Vytiniotis, Koen Claessen, Simon Peyton Jones, Dan Rosn POPL 2013, January 2013 1 Slide 2 Real programs contain assertions dimitris@artemis:~/GHC/ghc-head/ghc/compiler/typecheck$ grep -i ASSERT./*hs./FamInst.lhs: = ASSERT( isAlgTyCon tycon )./Inst.lhs: ; wrapASSERT( lvl == lvl1 ) id./TcEnv.lhs: TopLevel -&gt; ASSERT2( isEmptyVarSet id_tvs, ppr id $$ ppr (idType id) )./TcErrors.lhs: = ASSERT( isEmptyBag insols )./TcErrors.lhs: = ASSERT( not (null matches) )./TcErrors.lhs: = ASSERT( length matches &gt; 1 )./TcEvidence.lhs: | otherwise = ASSERT( arity &lt; n_tys )./TcEvidence.lhs:mkTcForAllCo tv (TcRefl ty) = ASSERT( isTyVar tv ) TcRefl (mkForAllTy tv ty)./TcEvidence.lhs:mkTcForAllCo tv co = ASSERT( isTyVar tv ) TcForAllCo tv co./TcEvidence.lhs:mkTcForAllCos tvs (TcRefl ty) = ASSERT( all isTyVar tvs ) TcRefl (mkForAllTys tvs ty)./TcEvidence.lhs:mkTcForAllCos tvs co = ASSERT( all isTyVar tvs ) foldr TcForAllCo co tvs./TcEvidence.lhs: = ASSERT (tc `hasKey` eqTyConKey)./TcEvidence.lhs: = ASSERT( equalLength tvs cos )./TcExpr.lhs: = ASSERT( not (isSigmaTy res_ty) )./TcExpr.lhs: = ASSERT( notNull upd_fld_names ) (from the GHC type checker) 2 Slide 3 This work Automated static verification of higher- order functional programs www.github.com/danr/contracts Tool works on subset of Haskell, uses GHC as frontend 3 Slide 4 Our setting Verify Haskell code: higher-order, lazy but pure Dont aim for high expressiveness, go for simple, easy-to-prove (e.g. structural) properties Automatically discharge all tedious but simple goals that a programmer has to manually and repeatedly check Re-use existing technology: Automated theorem provers (e.g. SMT solvers), model finders ACL2? Boogie? Prolog? Property-directed reachability? [Bjorner et al] No best solution yet. Our choice for this work 4 Slide 5 Programs and properties risers [] = [] risers [x] = [[x]] risers (x:y:ys) = case risers (y:ys) of [] -&gt; error urk (s:ss) -&gt; if x C2 | C1 &amp;&amp; C2 | CF Just an ordinary Haskell expression of type Bool crash-free 5 Slide 6 Design module Foo f x y = g x = -- Prelude data [a] = [] | a : as data Bool = True | False Functions over these Haskell Source First Order Logic Formulae Unsatisfiable Contract holds! HALO translation to First Order Logic Z3/Equinox/E/ Vampire/Paradox Theorem Prover Satisfiable Probably contract doesnt hold but who knows Cant tell anything 6 Slide 7 Key idea: let denotational semantics guide us A /case-lifted language Continuous function space Distinguished one-element cpo Lifting 7 Slide 8 Interpreted as injection into the appropriate product 8 Slide 9 Function definitions become FOL axioms head (Cons x xs) = x head _ = error 9 Slide 10 data List a = Cons a (List a)| Nil 10 Slide 11 Higher-order functions head (Cons x xs) = x head _ = error double f x = f (f x) 11 Slide 12 Refinements denotationally and logically Logically Denotationally 12 Slide 13 Soundness via denotational semantics 13 Slide 14 Automating induction Currently support fixpoint induction Assume contract holds for uninterpreted function add_rec NB: A sound thing to do by admissibility of contracts 14 Slide 15 Admissibility and why it matters In Haskell, data types are not inductive. Hence your familiar induction principle is simply unsound! ones = 1 : ones f Z = [] f (S x) = 1 : f x Lemma: forall x. f x ones Proof: Holds for UNR Holds for Z Assume holds for x; then holds for (S x) Right? WRONG! Let: u = S u Then: f u = ones Logical inequality, not admissible! 15 Slide 16 Admissibility and induction Admissibility = If P is true for all elements of a chain, then true for the limit. Not all predicates are admissible Comes for-free! Base contracts are Haskell functions, and those are continuous! 16 Slide 17 Happily implemented on top of GHC API Z3 rocks for provable properties! Disclaimer: 40-80 FOL axioms/problem Use of fixpoint induction 17 Slide 18 More features (and non-features) More features: Incremental verification Prove spec for g, use either the spec or definition of g, or both to prove other specifications Some support for lemmas Mutual (automatic) fixpoint induction Primitive arithmetic constraints via SMT2 (in Z3) Experimental features: logical equality, finite unfoldings Not there: Pre/post inference, strengthening of IH Support for counterexamples (see next slide) 18 Slide 19 Whats next: counterexamples 19 Unprovable contracts (because theyre false or were incomplete) Paradox Equinox Z3 Vampire E-prover AnyMorphism.big_sat_app_any_morphism_fail_step P:---- X:---- Z:---- V:---- E:---- Loop.sat_id_loop_pred P:0.00 X:0.01 Z:0.01 V:---- E:0.01 Loop.sat_id_recursive_true P:---- X:---- Z:---- V:---- E:0.01 PredLog.sat_concatMap_cf_missing_step P:---- X:---- Z:---- V:---- E:---- PredLog.sat_concatMap_retains_missing_step P:---- X:---- Z:---- V:---- E:---- PredLog.sat_flattenAnd_cf_missing_step P:---- X:---- Z:---- V:---- E:---- PredLog.sat_flattenAnd_retains_missing_step P:---- X:---- Z:---- V:---- E:----... Recursion.sat_qfac_cf_broken_step P:---- X:---- Z:---- V:---- E:---- Recursion.sat_rev_cf_broken_step P:---- X:---- Z:---- V:---- E:---- Risers.big_sat_risersBy_nonEmpty_broken2_step P:---- X:---- Z:---- V:---- E:---- Risers.big_sat_risersBy_nonEmpty_broken_step P:---- X:---- Z:---- V:---- E:---- Risers.sat_risers_broken2_step P:---- X:---- Z:---- V:---- E:---- Risers.sat_risers_broken3_step P:---- X:---- Z:---- V:---- E:---- Risers.sat_risers_broken_step P:---- X:---- Z:---- V:---- E:---- Risers.sat_risers_missing_le_step P:---- X:---- Z:---- V:---- E:---- Shrink.big_sat_shrink_lazy_step P:---- X:---- Z:---- V:---- E:---- Timeouts We now know why, and how to address this: stay tuned Slide 20 Whats next: usability Proving is reasonably fast, now explore: Automatic strengthening of induction hypotheses Pretty printing models as counterexamples More induction principles Testing in larger scale Interfacing with theorem provers for manual proofs? 20 Lots of man-hours needed, come help please! Slide 21 Related work Liquid Types [Jhala et al] Predicate abstraction Inference Quantifiers driven by type system ESC/Haskell [Xu et al] Contracts are programs Symbolic execution/inlining Zeno [Sonnex et al] Automated equality proofs Clever heuristics Strict semantics Catch [Mitchell] Pattern match errors Via dataflow analysis Dafny &amp; Boogie [Leino et al], ACL2 Leon [Suter et al] Specialized decision procedure for FP Good for first-order F7/F* [Swamy et al] Hoare logic for FP [Regis-Gianas &amp; Pottier] HO logics CBV *really* helps HO model checking, MoChi [Kobayashi et al] Specialized decision procedures Lots of techniques stacked Good for inference, good for counterexamples Symbolic execution-based [ Tobin- Hochstadt and Van Horn][Xu] Abstraction, lots of smaller queries to theorem prover HOLCF-based verification [Huffman] Reasoning in a very rich logic that contains formalization of a domain theory More sophisticated axiomatization, ability to reason about parametricity and monad laws Slide 22 What we did and what I learnt Weve given a semantic basis for the verification of Haskell programs We demonstrated that it is implementable 22 We can verify FP in a simple and robust way: For this particular case a simple solution seems to do the job. It appears affordable to use a very precise abstraction of your program and trust your 2013 theorem proving technology Thank you for your attention! </p>