Modules and Representa/on Invariants

Similar documents
Modules and Representation Invariants

Mutation. COS 326 David Walker Princeton University

A Func'onal Space Model

Sec$on 2: Specifica)on, ADTs, RI WITH MATERIAL FROM MANY

Thinking Induc,vely. COS 326 David Walker Princeton University

A Func'onal Introduc'on. COS 326 David Walker Princeton University

Implemen'ng OCaml in OCaml

More Untyped Lambda Calculus & Simply Typed Lambda Calculus

Vulnerability Analysis (III): Sta8c Analysis

Func%onal Decomposi%on

Program Verification (Rosen, Sections 5.5)

Bits, Bytes, and Integers

Writing a Fraction Class

Local defini1ons. Func1on mul1ples- of

Type Inference. COS 326 David Walker Princeton University

Recursive List Func.ons in Racket

Thinking Induc,vely. COS 326 David Walker Princeton University

Inductive Data Types

LING 581: Advanced Computa7onal Linguis7cs. Lecture Notes April 16th

h0ps://

The reader is referred to the Objective Caml reference manual for a more detailed description of these features.

CS261 Data Structures. Ordered Bag Dynamic Array Implementa;on

Founda'ons of So,ware Engineering. Sta$c analysis (1/2) Claire Le Goues

Lambda Calculus. Concepts in Programming Languages Recitation 6:

Programming Languages and Techniques (CIS120)

A Functional Space Model. COS 326 David Walker Princeton University

Lecture 2: Number Representa2on

M. Snyder, George Mason University LAMBDA CALCULUS. (untyped)

10/7/15. MediaItem tostring Method. Objec,ves. Using booleans in if statements. Review. Javadoc Guidelines

Applicatives Comparisons (2C) Young Won Lim 3/6/18

Approach starts with GEN and KILL sets

Harvard School of Engineering and Applied Sciences CS 152: Programming Languages

The Substitution Model. Nate Foster Spring 2018

Static Contract Checking for Haskell

Programming Languages and Techniques (CIS120)

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

Reasoning about programs

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

Overloading, Type Classes, and Algebraic Datatypes

CS558 Programming Languages

Programming Languages and Techniques (CIS120)

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

Outline. Integer representa+on and opera+ons Bit opera+ons Floa+ng point numbers. Reading Assignment:

Outline. Integer representa+on and opera+ons Bit opera+ons Floa+ng point numbers. Reading Assignment:

Floa.ng Point : Introduc;on to Computer Systems 4 th Lecture, Sep. 10, Instructors: Randal E. Bryant and David R.

CS 320: Concepts of Programming Languages

ATS: a language to make typeful programming real and fun

Standard ML. Data types. ML Datatypes.1

The Substitution Model

From Types to Contracts

Polymorphic lambda calculus Princ. of Progr. Languages (and Extended ) The University of Birmingham. c Uday Reddy

CS 11 Haskell track: lecture 1

Where we are SEMANTIC ANALYSIS. ! Program is lexically well- formed: ! Program is syntac,cally well- formed:

CIS 500 Software Foundations Midterm I

C Programming Primer 8/31/15 1

List Functions, and Higher-Order Functions

Lambda Calculi With Polymorphism

Type Systems. Parametric Polymorphism. 1. Recall Let-Polymorphism. 1. Recall Let-Polymorphism. Lecture 9 Dec. 15th, 2004 Sebastian Maneth

Course year Typeclasses and their instances

CSc 120. Introduc/on to Computer Programming II. 02: Problem Decomposi1on and Program Development. Adapted from slides by Dr.

PROGRAMMING IN HASKELL. Chapter 2 - First Steps

Faith, Evolution, and Programming Languages. Philip Wadler University of Edinburgh

Functional Programming. Lecture 2: Algebra

Lecture 15 CIS 341: COMPILERS

Cornell University 12 Oct Solutions. (a) [9 pts] For each of the 3 functions below, pick an appropriate type for it from the list below.

Programming with Math and Logic

CS: Formal Methods in Software Engineering

No model may be available. Software Abstractions. Recap on Model Checking. Model Checking for SW Verif. More on the big picture. Abst -> MC -> Refine

Assertions, pre/postconditions

(Func&onal (Programming (in (Scheme)))) Jianguo Lu

Testing. Prof. Clarkson Fall Today s music: Wrecking Ball by Miley Cyrus

Floats are not Reals. BIL 220 Introduc6on to Systems Programming Spring Instructors: Aykut & Erkut Erdem

State Monad (3D) Young Won Lim 8/31/17

Polymorphism Overview (1A) Young Won Lim 2/20/18

A CRASH COURSE IN SEMANTICS

61A LECTURE 14 MULTIPLE REPRESENTATIONS

A Small Interpreted Language

15 150: Principles of Functional Programming. More about Higher-Order Functions

Typed Racket: Racket with Static Types

61A LECTURE 14 MULTIPLE REPRESENTATIONS. Steven Tang and Eric Tzeng July 17, 2013

CSCE 314 Programming Languages Functors, Applicatives, and Monads

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

CSE 331 Final Exam 3/16/15 Sample Solution

Abstraction Functions and Representation Invariants

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

GHCi: Getting started (1A) Young Won Lim 6/3/17

Harvard School of Engineering and Applied Sciences Computer Science 152

Programming Languages and Compilers (CS 421)

Sign & Magnitude vs 2 s Complement ( Signed Integer Representa:ons)

Fall Lecture 3 September 4. Stephen Brookes

CMSC 330: Organization of Programming Languages

Functional Programming and Modeling

COS 320. Compiling Techniques

Proofs about Programs

Racket Values. cons Glues Two Values into a Pair. The Pros of cons: Programming with Pairs and Lists. Box-and-pointer diagrams for cons trees

Programming Languages Fall 2014

Clang Static Analyzer Documentation

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

EXAMINATIONS 2009 MID-TERM TEST. COMP 202 / SWEN 202 Formal Methods of Computer Science / Formal Foundations of Software Engineering WITH ANSWERS

CSE 331 Summer 2016 Final Exam. Please wait to turn the page until everyone is told to begin.

Transcription:

Modules and Representa/on Invariants COS 326 David Walker Princeton University slides copyright 2017 David Walker permission granted to reuse these slides for non-commercial educa/onal purposes

LAST TIME

Last Time: Representa/on Invariants A representa(on invariant inv(v) is a property that holds of all values of abstract type. Representa/on invariants can be used during debugging: check your outputs: call inv(v) on all outputs from the module of if you check all ouputs, then you should not need to check your inputs! (but you can, just in case you missed an output you should have checked! Proving representa/on invariants involves (roughly): Assuming invariants hold on inputs to func/ons Proving they hold on outputs to func/ons

Last Time: Module Equivalence Two modules with abstract will be declared equivalent if: one can define a rela(on between values of in the two modules, and one can show that the rela(on is preserved by all opera(ons As with representa/on invariants, one assumes the inputs to a func/on are related, and one proves that the outputs to the func/on are related. Example for modules M1 and M2 with nature S: define is_related(v1,v2) for v1 from M1 and v2 from M2 for all func/ons f : t -> t in S, prove: if is_related(v1,v2) then is_related(m1.f v1, M2.f v2)

ASIDE: WHAT DOES CHECKING YOUR "OUTPUTS" MEAN?

A simple program module type FOO = val create : int -> bool -> t val item : t... module FOO = = Either of int Or of int let create (n:int) (b:bool) : t = if b then Either n else Or (n*2) let item : t = Either 0

A simple program module type FOO = val create : int -> bool -> t val item : t... module FOO = = Either of int Or of int let create (n:int) (b:bool) : t = if b then Either n else Or (n*2) let item : t = Either 0 "outputs"

A simple program module type FOO = val create : int -> bool -> t val item : t... module FOO = = Either of int Or of int let inv (v:t) : t =... let check(v:t) (m:string) : t = if inv(v) then v else failwith m let create (n:int) (b:bool) : t = check ( if b then Either n else Or ((abs n)*2) ) let item : t = check (Either 0)

A simple program module type FOO = val create : int -> bool -> t val item : t val process : t -> t... client: let x = create 3 true in process x module FOO = = Either of int Or of int let inv (v:t) : t =... let check(v:t) (m:string) : t = if inv(v) then v else failwith m let process (v:t) : t = if not (inv v) then blow_up_the_world() (* undesirable! *) else... we want to be sure the world doesn't blow up. clients can obtain outputs and then pass them back as inputs to the module so we need to check the outputs.

A simple program module type FOO = val create : int -> bool -> t val item : t val process : t -> t val baz : (t -> unit) -> int... module FOO = = Either of int Or of int let baz (f:t -> unit) : int = let x = Or (-3) in f x; 17

A simple program module type FOO = val create : int -> bool -> t val item : t val process : t -> t val baz : (t -> unit) -> int... client: let f x = let _ = process x in () in baz f module FOO = = Either of int Or of int let process (v:t) : t = if not (inv v) then blow_up_the_world() else... let baz (f:t -> unit) : int = let x = Or (-3) in f x; 17

A simple program module type FOO = val create : int -> bool -> t val item : t val process : t -> t val baz : (t -> unit) -> int... client: let f x = let _ = process x in () in baz f module FOO = = Either of int Or of int let process (v:t) : t = if not (inv v) then blow_up_the_world() else... let baz (f:t -> unit) : int = let x = Or (-3) in f (check x); 17 need to check inputs to func/ons passed in as arguments!

A neat thing about types t1 -> t2 (t3 -> t4) -> t2 ((t5 -> t6) -> t4) -> t2 posi(ve posi(ons in types the posi/ons you have to check! the arrow -> acts like an operator that flips the "n" from posi/ve to nega/ve or nega/ve to posi/ve (((t7 -> t8) -> t6) -> t4) -> t2

A SIMPLE EXAMPLE

Represen/ng Ints module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num = = Zero Pos of int Neg of int let create (n:int) : t = if n = 0 then Zero else if n > 0 then Pos n else Neg (abs n) let equals (n1:t) (n2:t) : bool = match n1, n2 with Zero, Zero -> true Pos n, Pos m when n = m -> true Neg n, Neg m when n = m -> true _ -> false

Represen/ng Ints module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t = match t with Zero -> Neg 1 Pos n when n > 1 -> Pos (n-1) Pos n when n = 1 -> Zero Neg n -> Neg (n+1)

Represen/ng Ints module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t let inv (n:t) : bool = match n with Zero -> true Pos n when n > 0 -> true Neg n when n > 0 -> true _ -> false module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t = match t with Zero -> Neg 1 Pos n when n > 1 -> Pos (n-1) Pos n when n = 1 -> Zero Neg n -> Neg (n+1)

Represen/ng Ints module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t let inv (n:t) : bool = match n with Zero -> true Pos n when n > 0 -> true Neg n when n > 0 -> true _ -> false module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t = match t with Zero -> Neg 1 Pos n when n > 1 -> Pos (n-1) Pos n when n = 1 -> Zero Neg n -> Neg (n+1) To prove inv is a good rep invariant, prove that: (1) for all x:int, inv(create x) (2) nothing for equals (3) for all v1:t, if inv(v1) then inv(decr v1)

Represen/ng Ints module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let inv (n:t) : bool = match n with Zero -> true Pos n when n > 0 -> true Neg n when n > 0 -> true _ -> false let decr (n:t) : t = match t with Zero -> Neg 1 Pos n when n > 1 -> Pos (n-1) Pos n when n = 1 -> Zero Neg n -> Neg (n+1) once we have proven the rep inv, we can use it. eg, if we add abs to the module (and prove it doesn't violate the rep inv) then we can use inv to show that abs always returns a non-nega/ve number. let abs(n:t) : int = match t with Zero -> 0 Pos n -> n Neg n -> n

Another Implementa/on module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t let inv2 (n:t) : bool = true module Num2 = = int let create (n:int) : t = n let equals (n1:t) (n2:t) : bool = n1 = n2 let decr (n:t) : t = n - 1

Another Implementa/on module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num2 = = int let create (n:int) : t = n let equals (n1:t) (n2:t) : bool = n1 = n2 module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t =... let decr (n:t) : t = n - 1 Ques/on: can client programs tell Num, Num2 apart?

Another Implementa/on module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num2 = = int let create (n:int) : t = n let equals (n1:t) (n2:t) : bool = n1 = n2 module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t =... let decr (n:t) : t = n - 1 First, find rela/on between valid representa/ons of the.

Another Implementa/on module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num2 = = int let create (n:int) : t = n let equals (n1:t) (n2:t) : bool = n1 = n2 module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t =... let decr (n:t) : t = n - 1 First, find rela/on between valid representa/ons of the. let rel(x:t, y:int) : bool = match x with Zero -> y = 0 Pos n -> y = n Neg n -> -y = n

Another Implementa/on module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num2 = = int let create (n:int) : t = n let equals (n1:t) (n2:t) : bool = n1 = n2 module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t =... let decr (n:t) : t = n - 1 Next, prove the modules establish the rela/on.

Another Implementa/on module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num2 = = int let create (n:int) : t = n let equals (n1:t) (n2:t) : bool = n1 = n2 module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let decr (n:t) : t = n - 1 Next, prove the modules establish the rela/on. let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t =... for all x:int, rel (Num.create x) (Num2.create x)

Another Implementa/on module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num2 = = int let create (n:int) : t = n let equals (n1:t) (n2:t) : bool = n1 = n2 module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t =... let decr (n:t) : t = n - 1 Next, prove the modules establish the rela/on. for all x1,x2:t, y1,y2:int if inv(x1), inv(x2), inv2(y1), inv2(y2) and rel(x1,y1) and rel(x2,y2) then (Num.equals x1 x2) = (Num2.equals y1 y2)

Another Implementa/on module type NUM = val create : int -> t val equals : t -> t -> bool val decr : t -> t module Num2 = = int let create (n:int) : t = n let equals (n1:t) (n2:t) : bool = n1 = n2 module Num = = Zero Pos of int Neg of int let create (n:int) : t =... let equals (n1:t) (n2:t) : bool =... let decr (n:t) : t =... let decr (n:t) : t = n - 1 Next, prove the modules establish the rela/on. for all x1:t, y1:int if inv(x1) and inv2(y1) and rel(x1,y1) then rel (Num.decr x1) (Num2.decr y1)

Serial Killer or PL Researcher?

Serial Killer or PL Researcher? John Reynolds: super nice guy, 1935-2013 Discovered the polymorphic lambda calculus (first polymorphic type system). Developed Rela/onal Parametricity: A technique for proving the equivalence of modules. Luis Alfredo Garavito: super evil guy. In the 1990s killed between 139-400+ children in Colombia. According to wikipedia, killed more individuals than any other serial killer. Due to Colombian law, only imprisoned for 30 years; decreased to 22.

Summary: Debugging with Rep. Invariants = int let create n = abs n let incr n = n + 1 let apply (x, f) = f x = int let inv x : bool = x >= 0 let check_t x = assert (inv x); x let create n = check(abs n) let incr n = check ((check n) + 1) let apply (x, f) = check (f (check x)) It s good prac/ce to implement your representa/on invariants Use them to check your assump/ons about inputs find bugs in other func/ons Use them to check your outputs find bugs in your func/on check output produced check input assump/on

Summary: Rep. Invariants Proof Summary If a module M defines an abstract Think of a representa/on invariant inv(x) for values of Prove each value of type s provided by M is valid for type s rela/ve to the representa/on invariant If v : s then prove v is valid for type s as follows: if s is the abstract then prove inv(v) if s is a base type like int then v is always valid if s is s1 * s2 then prove: fst v is valid for type s1 snd v is valid for type s2 if s is s1 op/on then prove: v is None, or v is Some u and u is valid for type s1 Aside: This kind of proof is known as a proof using logical rela(ons. It lips a property on a basic type like inv( ) to a property on higher types like t1 * t2 and t1 -> t2 if s is s1 -> s2 then prove: for all x:s1, if x is valid for type s1 then v x is valid for type s2

Summary: Abstrac/on and Equivalence Abstrac/on func/ons define the rela/onship between a concrete implementa/on and the abstract view of the client We should prove concrete opera/ons implement abstract ones We prove any two modules are equivalent by Defining a rela/on between values of the modules with abstract type We get to assume the rela/on holds on inputs; prove it on outputs Rep invs and is_related predicates are called logical rela/ons