Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our User Agreement and Privacy Policy.

Slideshare uses cookies to improve functionality and performance, and to provide you with relevant advertising. If you continue browsing the site, you agree to the use of cookies on this website. See our Privacy Policy and User Agreement for details.

Successfully reported this slideshow.

Like this presentation? Why not share!

- Comparing Haskell and Scala by Martin Ockajak 3144 views
- Yampa AFRP Introduction by ChengHui Weng 467 views
- Graphical User Interfaces in Haskell by Gideon Sireling 857 views
- Constraint Programming in Haskell by David Overton 3688 views
- Comonads in Haskell by David Overton 7424 views
- Catch a spider monkey by ChengHui Weng 380 views

638 views

Published on

Published in:
Software

No Downloads

Total views

638

On SlideShare

0

From Embeds

0

Number of Embeds

8

Shares

0

Downloads

13

Comments

6

Likes

1

No notes for slide

- 1. Refinement types for Haskell
- 2. Martin Ockajak from Zürich Software Engineer @martin_ockajak
- 3. Outline ● Motivation ● Refinement types ● Liquid Haskell ● Practical considerations
- 4. Motivation
- 5. Standard type system ● Allows expressing certain properties of programs ● Type safety ● Verifiable without running the program ● Static type checking ● Integrated with the compilation ● Testing still needed ● Can we do better ?
- 6. Possible improvements ● Prevent more programming errors ● Division by zero ● Missing keys in maps ● Infinite loops ● Express properties of programs in greater detail ● Keep the ability to automatically verify type safety ● Verification must be a decidable problem ● No proofs by the programmer required
- 7. Refinement types
- 8. Refinement types ● Consist of ● Type ● Standard or refinement ● Predicate ● Propositional logic ● Can describe valid inputs and outputs of functions ● Type safe if the predicate is valid for all inputs
- 9. Predicate ● Boolean operators ● && , || , not , => , <=> , true , false ● Arithmetic operators ● + , - , * , / , mod ● Relations ● == , /= , < , > , <= , >=
- 10. Liquid Haskell
- 11. Liquid Haskell ● Static refinement type verifier ● Completely automatic ● Translates refinement types into verification conditions ● Satisfiability modulo theories formulas ● Uses an SMT solver to verify those conditions ● Without executing the program or enumerating inputs ● Project at University of California - San Diego ● http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/about/
- 12. Defining refinement types ● Positive is a subtype of NonZero ● Positive values are a subset of NonZero values {-@ type NonZero = {v: Int | v /= 0 } @-} {-@ type Positive = {v: Int | v > 0 } @-} {-@ type Odd = {v: Int | v mod 2 == 1 } @-} {-@ one :: NonZero @-} {-@ one :: Positive @-} {-@ one :: Odd @-} one :: Int one = 1 {-@ odds :: [Odd] @-} odds :: [Int] odds = [1, 3, 7]
- 13. Refining function results {-@ two :: {v: Int | v mod 2 == 0 } @-} {-@ one, two :: NonZero @-} two :: Int two = 1 + 1 {-@ size :: [a] -> {v: Int | v >= 0 } @-} size :: [a] -> Int size [] = 0 size (x:xs) = 1 + size xs {-@ positive :: n:Int -> { v: Bool | Prop v <=> n > 0 } @-} positive :: Int -> Bool positive n = n > 0
- 14. Refining function arguments {-@ crash :: {v: String | false } -> a @-} crash :: String -> a crash message = error message {-@ divide :: Int -> NonZero -> Int @-} divide :: Int -> Int -> Int divide n 0 = crash "division by zero" divide n d = n `div` d correctDivide :: Int correctDivide = divide 1 1 incorrectDivide :: Int incorrectDivide = divide 1 0
- 15. Defining predicates {-@ predicate Positive N = N > 0 @-} {-@ predicate Even N = N mod 2 == 0 @-} {-@ predicate PositiveOdd N = Positive N && not Even N @-} {-@ type Even = { v: Int | Even v } @-} {-@ three :: { v: Int | PositiveOdd v || v == 4 } @-} three :: Int three = 5 - 2
- 16. Measure functions ● Can be used inside refinement type definitions ● Single expression for every data constructor ● Propositional logic only data List a = Emp | (:::) a (List a) {-@ measure len @-} len :: List a -> Int len Emp = 0 len (x:::xs) = 1 + len xs {-@ first :: {v: List a | len v > 0 } -> a @-} first Emp = crash "empty list" first (x:::xs) = x
- 17. Refining data types ● Parametrized type alias used to specify list length data Triple a = Triple (List a) {-@ type ListN a N = {v: List a | len v == N} @-} {-@ data Triple a = Triple (ListN a 3) @-} correctTriple = Triple (1 ::: (2 ::: (3 ::: Emp)))
- 18. Inline functions and assumptions ● Inline functions can be used inside measures ● Assumptions allow describing non-verifiable functions {-@ inline increment2 @-} increment2 :: Int -> Int increment2 n = n + 2 {-@ measure doubleLen @-} doubleLen :: List a -> Int doubleLen Emp = 0 doubleLen (x:::xs) = increment2 (doubleLen xs) {-@ assume abs :: (Num a) => a -> {v: a | v > 0 } @-}
- 19. Recursion {-@ type NonNegative a = {v: a | v >= 0 } @-} {-@ type Natural a = {v: a | v > 0 } @-} {-@ fact :: (Integral a) => NonNegative a -> Natural a @-} fact :: (Integral a) => a -> a fact 0 = 1 fact n = n * fact (n – 1) correctFact = fact 3 incorrectFact = fact (-1)
- 20. Practical considerations
- 21. Practicality – Liquid Haskell ● Compatible with several SMT solvers ● Incremental checking support ● Decent documentation ● Still experimental
- 22. Thank you :-)

No public clipboards found for this slide

Login to see the comments