From Types to Contracts

Similar documents
Static Contract Checking for Haskell

Extended Static Checking for Haskell (ESC/Haskell)

Static Contract Checking for Haskell

Extended Static Checking for Haskell

Testing. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 2. [Faculty of Science Information and Computing Sciences]

MPRI course 2-4 Functional programming languages Exercises

QuickCheck, SmallCheck & Reach: Automated Testing in Haskell. Tom Shackell

Modules and Representation Invariants

Programming Languages Fall 2013

Type Theory meets Effects. Greg Morrisett

Combining Static and Dynamic Contract Checking for Curry

Lecture 6: Sequential Sorting

Simon Peyton Jones Microsoft Research August 2012

Programming Languages Lecture 14: Sum, Product, Recursive Types

CS 360: Programming Languages Lecture 10: Introduction to Haskell

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

Programming with dependent types: passing fad or useful tool?

Haskell Introduction Lists Other Structures Data Structures. Haskell Introduction. Mark Snyder

GADTs. Wouter Swierstra. Advanced functional programming - Lecture 7. Faculty of Science Information and Computing Sciences

Coq with Classes. Matthieu Sozeau. Journées PPS 2011 September 5th 2011 Trouville, France. Project Team πr 2 INRIA Paris

Functional Programming. Overview. Topics. Definition n-th Fibonacci Number. Graph

INTRODUCTION TO HASKELL

GADTs. Wouter Swierstra and Alejandro Serrano. Advanced functional programming - Lecture 7. [Faculty of Science Information and Computing Sciences]

Introduction to Haskell

GADTs. Alejandro Serrano. AFP Summer School. [Faculty of Science Information and Computing Sciences]

Reasoning About Imperative Programs. COS 441 Slides 10

Functional Programming for Logicians - Lecture 1

Functional Programming and Haskell

Shell CSCE 314 TAMU. Functions continued

CS 11 Haskell track: lecture 1

The Worker/Wrapper Transformation

Programming Languages 3. Definition and Proof by Induction

Finding and Fixing Bugs in Liquid Haskell. Anish Tondwalkar

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Winter 2013

CIS 500 Software Foundations Midterm I

CS 360: Programming Languages Lecture 12: More Haskell

Reasoning about programs

Practical Haskell. An introduction to functional programming. July 21, Practical Haskell. Juan Pedro Villa-Isaza. Introduction.

Last time. Reasoning about programs. Coming up. Project Final Presentations. This Thursday, Nov 30: 4 th in-class exercise

SOFTWARE VERIFICATION AND COMPUTER PROOF (lesson 1) Enrico Tassi Inria Sophia-Antipolis

Dependent Polymorphism. Makoto Hamana

Structural polymorphism in Generic Haskell

Pretty-Big-Step Semantics

Introduction to ML. Based on materials by Vitaly Shmatikov. General-purpose, non-c-like, non-oo language. Related languages: Haskell, Ocaml, F#,

Solution sheet 1. Introduction. Exercise 1 - Types of values. Exercise 2 - Constructors

Topic 7: Algebraic Data Types

CMSC 631 Program Analysis and Understanding. Dynamic Typing, Contracts, and Gradual Typing

CSCE 314 Programming Languages

Simon Peyton Jones Microsoft Research August 2013

Shell CSCE 314 TAMU. Higher Order Functions

Assertions, pre/postconditions

Main Goal. Language-independent program verification framework. Derive program properties from operational semantics

CS 161 Computer Security

Testing, Debugging, and Verification

Theorem Proving Principles, Techniques, Applications Recursion

Course year Typeclasses and their instances

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Advanced features of Functional Programming (Haskell)

The Worker/Wrapper Transformation

Functional Programming with Isabelle/HOL

Simply-Typed Lambda Calculus

More Untyped Lambda Calculus & Simply Typed Lambda Calculus

An introduction to functional programming. July 23, 2010

CS 6110 S11 Lecture 25 Typed λ-calculus 6 April 2011

Lambda Calculus. Concepts in Programming Languages Recitation 6:

Polymorphism. Lecture 19 CS 565 4/17/08

Logic - CM0845 Introduction to Haskell

Haskell 101. (Version 1 (July 18, 2012)) Juan Pedro Villa Isaza

CPM: A Declarative Package Manager with Semantic Versioning

Blockchains: new home for proven-correct software. Paris, Yoichi Hirai formal verification engineer, the Ethereum Foundation

Simon Peyton Jones (Microsoft Research) Max Bolingbroke (University of Cambridge)

Efficient Mergesort. Christian Sternagel. August 28, 2014

Functional Programming in Haskell Part I : Basics

FUNCTIONAL PEARLS The countdown problem

Dependent types and program equivalence. Stephanie Weirich, University of Pennsylvania with Limin Jia, Jianzhou Zhao, and Vilhelm Sjöberg

Program Verification (6EC version only)

Introduction to ML. Mooly Sagiv. Cornell CS 3110 Data Structures and Functional Programming

CMSC 330: Organization of Programming Languages. Functional Programming with Lists

Haskell An Introduction

Some Advanced ML Features

Type Processing by Constraint Reasoning

Concepts of program design Exam January 31, 13:30 16:30

Advanced Type System Features Tom Schrijvers. Leuven Haskell User Group

MSO Lecture Design by Contract"

Turning proof assistants into programming assistants

Introduction to OCaml

2

CSE341: Programming Languages Lecture 9 Function-Closure Idioms. Dan Grossman Fall 2011

Introduction to Programming: Lecture 6

The Substitution Model

Faster Haskell. Neil Mitchell

Functional Programming and Modeling

CSci 4223 Principles of Programming Languages

Induction for Data Types

List Functions, and Higher-Order Functions

Once Upon a Polymorphic Type

Programming Languages Fall 2014

Basic Foundations of Isabelle/HOL

Arbitrary-rank polymorphism in (GHC) Haskell

Transcription:

From Types to Contracts head [] = BAD head (x:xs) = x head :: [a] -> a (head 1) Bug! Type BAD means should not happen: crash null :: [a] - > Bool null [] = True null (x:xs) = False head {xs not (null xs)} -> {r True} (head []) Bug! Contract (arbitrary Haskell boolean expression)

What we want Adapt Findler- Felleisen s ideas for dynamic (high- order) contract checking. Do stahc contract checking for a lazy language. Contract Haskell function Glasgow Haskell Compiler (GHC) Where the bug is Why it is a bug

Three Outcomes (1) Definitely Safe (no crash, but may loop) (2) Definite Bug (definitely crashes) (3) Possible Bug

SorHng (==>) True x = x (==>) False x = True sorted [] = True sorted (x:[]) = True sorted (x:y:xs) = x <= y && sorted (y : xs) insert :: Int -> [Int] -> [Int] insert {i True} -> {xs sorted xs} -> {r sorted r} merge :: [Int] -> [Int] -> [Int] merge {xs sorted xs}->{ys sorted ys}->{r sorted r} bubblehelper :: [Int] -> ([Int], Bool) bubblehelper {xs True} -> {r not (snd r) ==> sorted (fst r)} insertsort, mergesort, bubblesort {xs True} -> {r sorted r} 5

AVL Tree (&&) True x = x (&&) False x = False balanced :: AVL -> Bool balanced L = True balanced (N t u) = balanced t && balanced u && abs (depth t - depth u) <= 1 data AVL = L N Int AVL AVL insert, delete :: AVL -> Int -> AVL insert {x balanced x} -> {y True} -> {r notleaf r && balanced r && 0 <= depth r - depth x && depth r - depth x <= 1 } delete {x balanced x} -> {y True} -> {r balanced r && 0 <= depth x - depth r && depth x - depth r <= 1}

The Contract Idea for Higher- Order FuncHon [Findler/Felleisen] f1 :: (Int -> Int) -> Int f1 ({x x > 0} -> {y y >= 0}) -> {r r >= 0} f1 g = (g 0) - 1 Blame f1: f1 calls g with wrong argument f1 does not sahsfy its post- condihon f2 :: {r True} f2 = f1 (\x -> x 5) f3 :: {r True} f3 = f1 (\x -> x 1) Can t tell at run-time Blame f2: f2 calls f1 with wrong argument f3 is Ok.

What is a Contract? Ok = {x True} arbitrary Haskell boolean expression Contract t ::= {x p} Predicate Contract x:t 1 -> t 2 Dependent Function Contract (t 1, t 2 ) Tuple Contract Any Polymorphic Any Contract 3 { x x > 0 } (3, []) Any 3 { x True } (3, []) (Ok, {ys null ys}) arbitrary constructor inc x:{x x>0} -> {y y == x + 1} Precondition Postcondition Postcondition can mention argument

What we want? Check f <contract_of_f> If main Ok, then the whole program cannot crash. If not, show which funchon to blame and why. Beauty of Contract Checking

Main Theorem e t iff e t is crash-free (related to Blume&McAllester:JFP 06) ESC/Haskell [Haskell 06] Symbolically simplify (e t) See if BAD is syntactically in e. If yes, DONE; else give BLAME [POPL 10] Define e t Construct e t (e ensures t) some e

Wrappers and ( pronounced ensures pronounced requires) e {x p} = case p[e/x] of True -> e False -> BAD e x:t 1 -> t 2 = λ v. (e (v t 1 )) t 2 [(v t 1 )/x] e (t 1, t 2 ) = case e of (e 1, e 2 ) -> (e 1 t 1, e 2 t 2 ) e Any = UNR related to [Findler-Felleisen:ICFP02]

Wrappers and ( pronounced ensures pronounced requires) e {x p} = case p[e/x] of True -> e False -> UNR e x:t 1 -> t 2 = λ v. (e (v t 1 )) t 2 [v t 1 /x] e (t 1, t 2 ) = case e of (e 1, e 2 ) -> (e 1 t 1, e 2 t 2 ) e Any = BAD related to [Findler-Felleisen:ICFP02]

Some InteresHng Details Theory Contracts that loop Contracts that crash Lovely Lemmas Practice Adding tags, e.g. BAD f Achieves precise blaming More tags to trace funchons to blame Achieves the same goal of [Meunier:POPL06] Using a theorem prover Counter- example guided unrolling

Lovely Lemmas

Summary StaHc contract checking is a ferhle and under- researched area DisHncHve features of our approach Full Haskell in contracts; absolutely crucial DeclaraHve specificahon of sahsfies Nice theory (with some very tricky corners) StaHc proofs Modular Checking Compiler as theorem prover

Afer Ph.D. Postdoc project in 2009: probabilishc contract for component base design [ATVA 2010] Current project at Xavier Leroy s team (INRIA) - a verifying compiler: 1. Apply the idea to OCaml compiler by allowing both stahc and dynamic contract checking 2. Connect with Coq to verify more programs stahcally. 3. Use Coq to prove the correctness of the framework. 4. Apply new ideas back to Haskell (e.g. GHC).

StaHc and Dynamic Static checking Program with Specifications Dynamic checking Compile Hme error amributes blame to the right place Run Hme error amributes blame to the right place No blaming means Program cannot crashs Or, more plausibly: If you guarantee that f t, then the program cannot crash

When does e sahsfy a contract? Brief, declarahve inc x:{x x > 0} -> {y y == x + 1} Precondition Postcondition Postcondition can mention argument

When does e sahsfy a contract? e is crash- free iff C. BAD s C. C[e] * BAD

Crash- free Examples Crash- free? \x -> x YES (1, True) YES (1, BAD) NO \x -> if x > 0 then x else (BAD, x) NO \x -> if x*x >= 0 then x + 1 else BAD Hmm.. YES Lemma: e is syntachcally safe => e is crash- free.

When does e sahsfy a contract? See the paper for Why e must be crash- free to sahsfy predicate contract? Why divergent expression sahsfies all contract? What if contract diverges (i.e. p diverges)? What if contract crashes (i.e. p crashes)?

head:: [a] -> a head [] = BAD head (x:xs) = x Example head { xs not (null xs) } -> Ok head {xs not (null xs)} -> Ok = \v. head (v {xs not (null xs)}) Ok e Ok = e = \v. head (v {xs not (null xs)}) = \v. head (case not (null v) of True -> v False -> UNR)

\v. head (case not (null v) of True -> v False -> UNR) Now inline not and null = \v. head (case v of [] -> UNR (p:ps) -> p) null :: [a] -> Bool null [] = True null (x:xs) = False not :: Bool -> Bool not True = False not False = True Now inline head = \v. case v of [] -> UNR (p:ps) -> p head:: [a] -> a head [] = BAD head (x:xs) = x So head [] fails with UNR, not BAD, blaming the caller

[Flanaghan, Mitchell, Pottier] Static checking StaHc and Dynamic Compile Hme error amributes blame to the right place Program with Specifications Dynamic checking Run Hme error amributes blame to the right place [Findler, Felleisen, Blume, Hinze, Loh, Runciman, Chitil]