Combining Static and Dynamic Contract Checking for Curry

Similar documents
CPM: A Declarative Package Manager with Semantic Versioning

Concolic Testing of Functional Logic Programs

Multi-paradigm Declarative Languages

Functional Logic Programming Language Curry

Declarative Programming with Function Patterns

Extended Static Checking for Haskell (ESC/Haskell)

Assertions, pre/postconditions

PROGRAMMING IN HASKELL. CS Chapter 6 - Recursive Functions

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

1 Introduction. 3 Syntax

CSCI-GA Scripting Languages

CMSC 330: Organization of Programming Languages

Recursion. Tjark Weber. Functional Programming 1. Based on notes by Sven-Olof Nyström. Tjark Weber (UU) Recursion 1 / 37

Overlapping Rules and Logic Variables in Functional Logic Programs

Haske k ll An introduction to Functional functional programming using Haskell Purely Lazy Example: QuickSort in Java Example: QuickSort in Haskell

An introduction introduction to functional functional programming programming using usin Haskell

Static Contract Checking for Haskell

Functional Logic Design Patterns

COP4020 Programming Languages. Functional Programming Prof. Robert van Engelen

Lecture #13: Type Inference and Unification. Typing In the Language ML. Type Inference. Doing Type Inference

Programming Languages Fall 2013

Functional Logic Programming: From Theory to Curry

Abstract Interpretation

Programming Languages 3. Definition and Proof by Induction

CSCE 314 TAMU Fall CSCE 314: Programming Languages Dr. Flemming Andersen. Haskell Functions

Lecture #23: Conversion and Type Inference

Conversion vs. Subtyping. Lecture #23: Conversion and Type Inference. Integer Conversions. Conversions: Implicit vs. Explicit. Object x = "Hello";

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

Shell CSCE 314 TAMU. Haskell Functions

The Worker/Wrapper Transformation

A Brief Introduction to Standard ML

Declarative Multi-Paradigm Programming in

Introduction to OCaml

Part II. Hoare Logic and Program Verification. Why specify programs? Specification and Verification. Code Verification. Why verify programs?

Programming Languages Third Edition

Shell CSCE 314 TAMU. Functions continued

Runtime Checking and Test Case Generation for Python

Multi-paradigm Declarative Languages

An introduction to functional programming. July 23, 2010

Software Development. Modular Design and Algorithm Analysis

Introduction to SML Getting Started

Exercise 1 ( = 24 points)

Default Rules for Curry

CS 11 Haskell track: lecture 1

CS421 Spring 2014 Midterm 1

Functional Logic Programming. Kristjan Vedel

CS 457/557: Functional Languages

A CRASH COURSE IN SEMANTICS

The design of a programming language for provably correct programs: success and failure

COMP 4161 NICTA Advanced Course. Advanced Topics in Software Verification. Toby Murray, June Andronick, Gerwin Klein

CS 340 Spring 2019 Midterm Exam

High-performance defunctionalization in Futhark

CMSC 330: Organization of Programming Languages. Formal Semantics of a Prog. Lang. Specifying Syntax, Semantics

Lecture 19: Functions, Types and Data Structures in Haskell

Lists. Michael P. Fourman. February 2, 2010

LECTURE 16. Functional Programming

Rethinking Automated Theorem Provers?

CSC Advanced Object Oriented Programming, Spring Specification

Programming Languages Lecture 14: Sum, Product, Recursive Types

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

Denotational Semantics. Domain Theory

Recursion. Lars-Henrik Eriksson. Functional Programming 1. Based on a presentation by Tjark Weber and notes by Sven-Olof Nyström

CSC312 Principles of Programming Languages : Functional Programming Language. Copyright 2006 The McGraw-Hill Companies, Inc.

λ calculus is inconsistent

Static program checking and verification

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

Programming Languages

An Operational and Axiomatic Semantics for Non-determinism and Sequence Points in C

CS131 Typed Lambda Calculus Worksheet Due Thursday, April 19th

Static Program Analysis Part 1 the TIP language

Semantics of programming languages

Haskell through HUGS THE BASICS

Lambda Calculus and Type Inference

A Semantics for Tracing Declarative Multi-Paradigm Programs

Advanced features of Functional Programming (Haskell)

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

15 212: Principles of Programming. Some Notes on Induction

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

02157 Functional Programming. Michael R. Ha. Lecture 2: Functions, Types and Lists. Michael R. Hansen

Axiomatic Rules. Lecture 18: Axiomatic Semantics & Type Safety. Correctness using Axioms & Rules. Axiomatic Rules. Steps in Proof

CS4215 Programming Language Implementation. Martin Henz

Haskell Overview II (2A) Young Won Lim 8/9/16

The University of Nottingham

Principles of Program Analysis: A Sampler of Approaches

Advanced Type System Features Tom Schrijvers. Leuven Haskell User Group

Lambda Calculus and Type Inference

Declarative Multi-paradigm Programming

Towards a Safe Partial Evaluation of Lazy Functional Logic Programs

Variables and Bindings

INTRODUCTION TO HASKELL

Continuation Passing Style. Continuation Passing Style

Reasoning about programs. Chapter 9 of Thompson

A Practical Approach to Programming With Assertions

Chapter 3 Linear Structures: Lists

Logic - CM0845 Introduction to Haskell

Violations of the contract are exceptions, and are usually handled by special language constructs. Design by contract

CSC324- TUTORIAL 5. Shems Saleh* *Some slides inspired by/based on Afsaneh Fazly s slides

Booleans (aka Truth Values) Programming Languages and Compilers (CS 421) Booleans and Short-Circuit Evaluation. Tuples as Values.

Handout 2 August 25, 2008

A Proposal for a More Generic, More Accountable, Verilog DCC 2010

Transcription:

Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 1 Combining Static and Dynamic Contract Checking for Curry Michael Hanus University of Kiel Programming Languages and Compiler Construction LOPSTR 2017

Developing Reliable Software Systems Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 2 Program verification... perfect but not practical: difficult proofs, no fully automatic tools exact proof obligations / specifications Declarative programming... good but not perfect: run-time errors exist objective: avoid possible run-time errors Pragmatic approach: combine static and dynamic checks strong typing static detection of some run-time errors more complex conditions dynamic assertions Our approach: Move boundaries by static verification of dynamic assertions

Combining Static and Dynamic Checking Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 3 Advantages fully automatic approach more efficient reliable software fac :: Int Int fac n = if n==0 then 1 else n * fac (n-1) fac "Hello": statically rejected fac (2-5): still possible infinite loop Add contracts (pre/postconditions) [PADL 12]: fac pre n = n >= 0 fac post n f = f > 0 fac (x-2-x): rejected at run time

Contract Verification Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 4 Dynamic contract checking requires additional execution time often turned off in production systems Our approach try to verify contracts at compile time if successful: remove dynamic contract checks otherwise: leave dynamic checks Advantages reliable program execution more efficient (if successful) practical (if fully automatic)

Proof of Concept Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 5 Programming language: Curry declarative (functional logic) language results applicable to functional as well as logic languages Verification: SMT solver fully automatic prover quite powerful for integers and algebraic types

Functional Logic Programming with Curry Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 6 Curry: Haskell syntax, logic features (non-determinism) Functions: concatenating lists [] ++ ys = ys (x:xs) ++ ys = x : (xs ++ ys) Non-determinism: list insertion + permutation ins x ys = x : ys ins x (y:ys) = y : ins x ys > ins 0 [1,2] [0,1,2]? [1,0,2]? [1,2,0] perm [] = [] perm (x:xs) = ins x (perm xs)

Contracts for Curry [PADL 12] Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 7 Given: f :: τ τ Contract for f : pre- and postcondition Precondition: f pre :: τ Bool Postcondition: f post :: τ τ Bool Dynamic contract checking Curry preprocessor transforms contracts into dynamic checks: precondition check arguments before each call postcondition check arguments/result after evaluation

Contract Verification: Motivation Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 8 Factorial operation with contract: fac :: Int Int fac n = if n==0 then 1 else n * fac (n-1) fac pre n = n >= 0 fac post n f = f > 0 Consider evaluation of f n: without contract checking: n calls with contract checking: n calls + 2 n contract calls

Contract Verification Verifying precondition fac n = if n==0 then 1 else n * fac (n-1) fac pre n = n >= 0 Consider recursive fac call: n>=0 (by precondition) (n==0) (since else branch is chosen) n>=0 (n==0) = (n-1)>=0 (by SMT solver) precondition of recursive call always satisfied, omit at run-time Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 9

Contract Verification Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 10 Verifying postcondition fac n = if n==0 then 1 else n * fac (n-1) fac post n f = f > 0 Consider value of right-hand side: 1 then branch: 1 > 0 postcondition satisfied 2 else branch: n>=0 (by precondition) (n==0) (since else branch is chosen) fac(n-1)>0 (by postcondition) n>=0 (n==0) fac(n-1)>0 = n*fac(n-1)>0 (by SMT) postcondition satisfied Altogether: postcondition always satisfied, omit at run-time

Contract Verification Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 11 Combining pre- and postcondition verification fac :: Int Int fac n = if n==0 then 1 else n * fac (n-1) fac pre n = n >= 0 fac post n f = f > 0 g n = fac (fac n) Consider outermost call to fac in g: (fac n)>0 (by postcondition) (fac n)>0 = (fac n)>=0 (by SMT) omit precondition check for this call

Formalization Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 12 For simplicity: use normalized FlatCurry representation fac(n) = let x = 0 y = n==x in case y of True 1 False let n1 = n - 1 f = fac n1 in n * f natural semantics for Curry [Albert et al. JSC 05] paper: include contract checking Abstract assertion-collecting semantics 1 compute with symbolic values instead of concrete ones 2 collect properties that are known to be valid 3 do not evaluate functions (termination!) but collect their pre- and postconditions

Abstract Assertion-Collecting Semantics Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 13 Val Γ : C z v C z = v where v constructor-rooted or v variable not bound in Γ VarExp Γ : C z e D Γ[x e] : C z x D Fun Γ : C z f (x n ) C f pre(x n ) f post(x n, z) Let Γ[y k ρ(e k )] : C z ρ(e) D Γ : C z let {x k = e k } in e D where ρ = {x k y k } and y k fresh Or Select Γ : C z e 1 D 1 Γ : C z e 2 D 2 Γ : C z e 1 or e 2 D 1 D 2 Γ : C x x D Γ : D 1 z e 1 E 1... Γ : D k z e k E k Γ : C z case x of {p k e k } E 1... E k where D i = D x = p i (i = 1,..., k)

Assertion-Collecting Semantics: Example Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 14 fac(n) = let x = 0 y = n==x in case y of True 1 False let n1 = n - 1 f = fac n1 in n * f Collected assertions for right-hand side: n>=0 x=0 y=(n=x) ((y=true z=1) (y=false n1=n-1 f>0 z=n*f)) = z>0 (by SMT solver) postcondition verified

Assertion-Collecting Semantics: Main Result Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 15 The correctness of our approach is justified by Theorem (Correctness of abstract assertion collection) Let e be an expression. If e evaluates to v and the abstract semantics collects, for z = e, the assertion C, then z = v C.

More Examples Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 16 last [x] = x last (_:x:xs) = last (x:xs) last pre xs = not (null xs) Omit precondition of recursive call if not (null xs) xs = (y:ys) ys = (z:zs) = not (null (z:zs)) by evaluating right-hand side to true

More Examples Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 17 Select nth element of a list nth (x:xs) n n==0 = x n>0 = nth xs (n-1) nth pre xs n = n>=0 && length (take (n+1) xs) == n+1 Omit precondition of recursive call if implies n 0 length (take (n + 1) xs) = n + 1 xs = (y:ys) n 0 n > 0 (n 1) 0 length (take ((n 1) + 1) ys) = (n 1) + 1 (by SMT solver with axiomatization of operations length and take)

Implementation Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 18 Contract verification tool 1 Curry preprocessor performs source-level transformation: add contracts as run-time checks 2 Preprocessed program transformed into FlatCurry program 3 For each contract: extract proof obligation 4 For each proof obligation: translate into SMT-LIB format and send to SMT solver (here: Z3) 5 If SMT solver proves validity: remove check from FlatCurry program

Benchmarks Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 19 Run time in seconds (0.00 < 10ms) Expression dynamic static+dynamic speedup fac 20 0.00 0.00 n.a. sum 1000000 0.84 0.22 3.88 fib 35 1.95 0.60 3.23 last [1..20000000] 0.63 0.35 1.78 take 200000 [1..] 0.31 0.19 1.68 nth [1..] 50000 26.33 0.01 2633 allnats 200000 0.27 0.19 1.40 init [1..10000] 2.78 0.00 >277 [1..20000] ++ [1..1000] 4.21 0.00 >420 nrev [1..1000] 3.50 0.00 >349 rev [1..10000] 1.88 0.00 >188 init, (++), nrev, rev: postcondition on length of lists

Conclusions Michael Hanus (CAU Kiel) Combining Static and Dynamic Contract Checking for Curry LOPSTR 2017 20 Combining static and dynamic contract checking support reliable software by adding contracts (more complex than standard types) disadvantage: run-time overhead avoid overhead by static verification if successful: run time reduction ( benchmarks) higher confidence in overall quality of application Future work more examples... better contract reduction: omit verified parts of contracts use counter-examples from verifier to check actual contract violation integrate abstract interpretation techniques for better precision