Programming Languages Fall 2013

Similar documents
Programming Languages and Types

Notes from Yesterday s Discussion. Big Picture. CIS 500 Software Foundations Fall November 1. Some lessons.

CIS 500 Software Foundations Fall October. Review. Administrivia. Subtyping

CS 6110 Lecture 28 Subtype Polymorphism 3 April 2013 Lecturer: Andrew Myers

CIS 500 Software Foundations Final Exam Answer key December 20, 2004

CIS 500 Software Foundations Final Exam. Answer key. December 20, 2006

CS 4110 Programming Languages & Logics. Lecture 25 Records and Subtyping

Simply Typed Lambda Calculus

Type Systems Winter Semester 2006

CIS 500 Software Foundations Midterm II Answer key November 17, 2004

Formal Methods Lecture 6. (B. Pierce's slides for the book Types and Programming Languages )

Lecture Notes on Certifying Theorem Provers

CIS 500 Software Foundations Final Exam Answer key December 14, 2005

Formal Methods Lecture 6. (B. Pierce's slides for the book Types and Programming Languages )

Lecture Notes on Heyting Arithmetic

CSCI 490 problem set 6

CS 4110 Programming Languages & Logics. Lecture 16 Programming in the λ-calculus

Polymorphism, Subtyping, and Type Inference in MLsub

Lecture Notes on The Curry-Howard Isomorphism

Typed Arithmetic Expressions

Typing λ-terms. Types. Typed λ-terms. Base Types. The Typing Relation. Advanced Formal Methods. Lecture 3: Simply Typed Lambda calculus

Hoare Logic: Reasoning About Imperative Programs

CIS 500 Software Foundations. Final Exam. May 9, Answer key. Hoare Logic

A Monadic Analysis of Information Flow Security with Mutable State

NICTA Advanced Course. Theorem Proving Principles, Techniques, Applications

Type Systems Winter Semester 2006

Notes on Inductive Sets and Induction

1 Closest Pair of Points on the Plane

Kirsten Lackner Solberg. Dept. of Math. and Computer Science. Odense University, Denmark

Program-ing in Coq. Matthieu Sozeau under the direction of Christine Paulin-Mohring

Mathematical Foundations of Programming. Nicolai Kraus. Draft of February 15, 2018

Modal and temporal logic

Induction on Failing Derivations

Computability Crib Sheet

Safety Analysis versus Type Inference

Lecture Notes on Data Abstraction

Static Program Analysis

Deduction by Daniel Bonevac. Chapter 3 Truth Trees

CSE505, Fall 2012, Final Examination December 10, 2012

Real Analysis Prof. S.H. Kulkarni Department of Mathematics Indian Institute of Technology, Madras. Lecture - 13 Conditional Convergence

What is logic, the topic of this course? There are at least two answers to that question.

Evaluation Driven Proof-Search in Natural Deduction Calculi for Intuitionistic Propositional Logic

Lecture Notes on Inductive Definitions

Safety Analysis versus Type Inference for Partial Types

References. 7 November. Fall Software Foundations CIS 500. Another example. Announcements. Homework 7 out today, due November 14.

Element x is R-minimal in X if y X. R(y, x).

Relational Reasoning in Natural Language

3.2 Reduction 29. Truth. The constructor just forms the unit element,. Since there is no destructor, there is no reduction rule.

Proving Completeness for Nested Sequent Calculi 1

COMPUTER SCIENCE TRIPOS

Limitations of OCAML records

Mathematical Logic Prof. Arindama Singh Department of Mathematics Indian Institute of Technology, Madras. Lecture - 15 Propositional Calculus (PC)

Taming Selective Strictness

Logic: The Big Picture

Proving languages to be nonregular

The Locally Nameless Representation

CISC 4090: Theory of Computation Chapter 1 Regular Languages. Section 1.1: Finite Automata. What is a computer? Finite automata

Lecture 10: Gentzen Systems to Refinement Logic CS 4860 Spring 2009 Thursday, February 19, 2009

Truth-Functional Logic

Natural Deduction for Propositional Logic

Introduction to lambda calculus Part 6

Imperative Insertion Sort

Math (P)Review Part II:

Models of Computation,

EDA045F: Program Analysis LECTURE 10: TYPES 1. Christoph Reichenbach

Lecture Notes on Inductive Definitions

Math 38: Graph Theory Spring 2004 Dartmouth College. On Writing Proofs. 1 Introduction. 2 Finding A Solution

Supplementary Notes on Inductive Definitions

Lecture 6 : Induction DRAFT

Information Flow Inference for ML

Applied Logic. Lecture 1 - Propositional logic. Marcin Szczuka. Institute of Informatics, The University of Warsaw

Type Soundness for Path Polymorphism

Solving recurrences. Frequently showing up when analysing divide&conquer algorithms or, more generally, recursive algorithms.

Erasable Contracts. Abstract. 1. Introduction. Harvard University {jchinlee,

CS411 Notes 3 Induction and Recursion

CMSC 631 Program Analysis and Understanding Fall Type Systems

15-251: Great Theoretical Ideas In Computer Science Recitation 9 : Randomized Algorithms and Communication Complexity Solutions

CS280, Spring 2004: Final

Simply Typed Lambda Calculus

Programming with Dependent Types in Coq

Extensions to the Logic of All x are y: Verbs, Relative Clauses, and Only

Structural Induction

Clojure Concurrency Constructs, Part Two. CSCI 5828: Foundations of Software Engineering Lecture 13 10/07/2014

Lecture Notes on Focusing

Lazy Strong Normalization

Lectures Notes on Progress

Monadic Refinements for Relational Cost Analysis (Appendix)

Reasoning About Programs Panagiotis Manolios

Lecture 13: Soundness, Completeness and Compactness

(Refer Slide Time: 0:21)

COMP6463: λ-calculus

Mechanizing a Decision Procedure for Coproduct Equality in Twelf

Lecture 11: Measuring the Complexity of Proofs

UNTYPED LAMBDA CALCULUS (II)

Lebesgue measure and integration

NP-Completeness I. Lecture Overview Introduction: Reduction and Expressiveness

3 Polymorphic Manifest Contracts, Revised and Resolved

Lecture Notes on Compositional Reasoning

Mathematical Logic. Introduction to Reasoning and Automated Reasoning. Hilbert-style Propositional Reasoning. Chiara Ghidini. FBK-IRST, Trento, Italy

Chapter 2. Mathematical Reasoning. 2.1 Mathematical Models

Transcription:

Programming Languages Fall 2013 Lecture 11: Subtyping Prof Liang Huang huang@qccscunyedu

Big Picture Part I: Fundamentals Functional Programming and Basic Haskell Proof by Induction and Structural Induction Part II: Simply-Typed Lambda-Calculus Untyped Lambda Calculus Simply Typed Lambda Calculus Extensions: Units, Records, Variants References and Memory Allocation Part III: Object-Oriented Programming Basic Subtyping Case Study: Featherweight Java class A extends Object { A() { super(); } } class B extends Object { B() { super(); } } class Pair extends Object { Object fst; Object snd; // Constructor: Pair(Object fst, Object snd) { super(); thisfst=fst; thissnd=snd;} // Method definition: Pair setfst(object newfst) { return new Pair(newfst, thissnd); }} 2

Subtyping

Motivation With our usual typing rule for applications ` t 1 : T 11!T 12 ` t 2 : T 11 ` t 1 t 2 : T 12 (T-App) the term ( r:{x:nat} rx) {x=0,y=1} is not well typed

Motivation With our usual typing rule for applications ` t 1 : T 11!T 12 ` t 2 : T 11 ` t 1 t 2 : T 12 (T-App) the term ( r:{x:nat} rx) {x=0,y=1} is not well typed But this is silly: all we re doing is passing the function a better argument than it needs

Polymorphism A polymorphic function may be applied to many di erent types of data Varieties of polymorphism: I Parametric polymorphism (ML-style) I Subtype polymorphism (OO-style) I Ad-hoc polymorphism (overloading) C++ templates C++ subclass C++ operator overloading Our topic for the next few lectures is subtype polymorphism, which is based on the idea of subsumption

Subsumption More generally: some types are better than others, in the sense that a value of one can always safely be used where a value of the other is expected We can formalize this intuition by introducing 1 a subtyping relation between types, written S <: T 2 a rule of subsumption stating that, if S <: T, then any value of type S can also be regarded as having type T ` t : S ` t : T S <: T (T-Sub)

Example We will define subtyping between record types so that, for example, {x:nat, y:nat} <: {x:nat} So, by subsumption, ` {x=0,y=1} : {x:nat} and hence ( r:{x:nat} rx) {x=0,y=1} is well typed

The Subtype Relation: Records Width subtyping (forgetting fields on the right): {l i :T i i21n+k } <: {l i :T i i21n } (S-RcdWidth) Intuition: {x:nat} is the type of all records with at least a numeric x field Note that the record type with more fields is a subtype of the record type with fewer fields Reason: the type with more fields places a stronger constraint on values, so it describes fewer values

The Subtype Relation: Records Permutation of fields: {k j :S j j21n } is a permutation of {l i :T i i21n } {k j :S j j21n } <: {l i :T i i21n } (S-RcdPerm) By using S-RcdPerm together with S-RcdWidth and S-Trans allows us to drop arbitrary fields within records

The Subtype Relation: Records Depth subtyping within fields: for each i S i <: T i {l i :S i i21n } <: {l i :T i i21n } (S-RcdDepth) The types of individual fields may change

Example {a:nat,b:nat} <: {a:nat} S-RcdWidth {m:nat} <: {} {x:{a:nat,b:nat},y:{m:nat}} <: {x:{a:nat},y:{}} S-RcdWidth S-RcdDepth

Variations Real languages often choose not to adopt all of these record subtyping rules For example, in Java, I A subclass may not change the argument or result types of a method of its superclass (ie, no depth subtyping) I Each class has just one superclass ( single inheritance of classes)! each class member (field or method) can be assigned a single index, adding new indices on the right as more members are added in subclasses (ie, no permutation for classes) I A class may implement multiple interfaces ( multiple inheritance of interfaces) Ie, permutation is allowed for interfaces

The Subtype Relation: Arrow types T 1 <: S 1 S 2 <: T 2 S 1!S 2 <: T 1!T 2 (S-Arrow) Note the order of T 1 and S 1 in the first premise The subtype relation is contravariant in the left-hand sides of arrows and covariant in the right-hand sides Intuition: if we have a function f of type S 1!S 2, then we know that f accepts elements of type S 1 ; clearly, f will also accept elements of any subtype T 1 of S 1 The type of f also tells us that it returns elements of type S 2 ; we can also view these results belonging to any supertype T 2 of S 2 That is, any function f of type S 1!S 2 can also be viewed as having type T 1!T 2

Motivation now let s typecheck this example With our usual typing rule for applications ` t 1 : T 11!T 12 ` t 2 : T 11 ` t 1 t 2 : T 12 (T-App) the term ( r:{x:nat} rx) {x=0,y=1} is not well typed

The Subtype Relation: Top It is convenient to have a type that is a supertype of every type We introduce a new type constant Top, plus a rule that makes Top a maximum element of the subtype relation S <: Top (S-Top) Cf Object in Java

The Subtype Relation: General rules S <: S S <: U U <: T S <: T (S-Refl) (S-Trans)

Subtype relation S <: S S <: U U <: T S <: T (S-Refl) (S-Trans) {l i :T i i21n+k } <: {l i :T i i21n } (S-RcdWidth) for each i S i <: T i {l i :S i i21n } <: {l i :T i i21n } (S-RcdDepth) {k j :S j j21n } is a permutation of {l i :T i i21n } {k j :S j j21n } <: {l i :T i i21n } (S-RcdPerm) T 1 <: S 1 S 2 <: T 2 S 1!S 2 <: T 1!T 2 S <: Top (S-Arrow) (S-Top)

Properties of Subtyping

Safety Statements of progress and preservation theorems are unchanged from! Proofs become a bit more involved, because the typing relation is no longer syntax directed Given a derivation, we don t always know what rule was used in the last step The rule T-Sub could appear anywhere ` t : S ` t : T S <: T (T-Sub)

Preservation Theorem: If ` t : T and t! t 0, then ` t 0 : T Proof: By induction on typing derivations (Which cases are likely to be hard?)

Subsumption case Case T-Sub: t : S S <: T

Subsumption case Case T-Sub: t : S S <: T By the induction hypothesis, ` t 0 : S By T-Sub, ` t : T

Subsumption case Case T-Sub: t : S S <: T By the induction hypothesis, ` t 0 : S By T-Sub, ` t : T Not hard!

Application case Case T-App: t = t 1 t 2 ` t 1 : T 11!T 12 ` t 2 : T 11 T = T 12 By the inversion lemma for evaluation, there are three rules by which t! t 0 can be derived: E-App1, E-App2, and E-AppAbs Proceed by cases

Application case Case T-App: t = t 1 t 2 ` t 1 : T 11!T 12 ` t 2 : T 11 T = T 12 By the inversion lemma for evaluation, there are three rules by which t! t 0 can be derived: E-App1, E-App2, and E-AppAbs Proceed by cases Subcase E-App1: t 1! t 0 1 t 0 = t 0 1 t 2 The result follows from the induction hypothesis and T-App ` t 1 : T 11!T 12 ` t 2 : T 11 ` t 1 t 2 : T 12 (T-App)

Application case Case T-App: t = t 1 t 2 ` t 1 : T 11!T 12 ` t 2 : T 11 T = T 12 By the inversion lemma for evaluation, there are three rules by which t! t 0 can be derived: E-App1, E-App2, and E-AppAbs Proceed by cases Subcase E-App1: t 1! t 0 1 t 0 = t 0 1 t 2 The result follows from the induction hypothesis and T-App ` t 1 : T 11!T 12 ` t 2 : T 11 ` t 1 t 2 : T 12 (T-App) t 1! t 0 1 t 1 t 2! t 0 1 t 2 (E-App1)

Case T-App (continued): t = t 1 t 2 ` t 1 : T 11!T 12 ` t 2 : T 11 T = T 12 Subcase E-App2: t 1 = v 1 t 2! t 0 2 t 0 = v 1 t 0 2 Similar ` t 1 : T 11!T 12 ` t 2 : T 11 ` t 1 t 2 : T 12 (T-App) t 2! t 0 2 v 1 t 2! v 1 t 0 2 (E-App2)

Case T-App (continued): t = t 1 t 2 ` t 1 : T 11!T 12 ` t 2 : T 11 T = T 12 Subcase E-AppAbs: t 1 = x:s 11 t 12 t 2 = v 2 t 0 =[x 7! v 2 ]t 12 By the inversion lemma for the typing relation

Case T-App (continued): t = t 1 t 2 ` t 1 : T 11!T 12 ` t 2 : T 11 T = T 12 Subcase E-AppAbs: t 1 = x:s 11 t 12 t 2 = v 2 t 0 =[x 7! v 2 ]t 12 By the inversion lemma for the typing relation T 11 <: S 11 and, x:s 11 ` t 12 : T 12

Case T-App (continued): t = t 1 t 2 ` t 1 : T 11!T 12 ` t 2 : T 11 T = T 12 Subcase E-AppAbs: t 1 = x:s 11 t 12 t 2 = v 2 t 0 =[x 7! v 2 ]t 12 By the inversion lemma for the typing relation T 11 <: S 11 and, x:s 11 ` t 12 : T 12 By T-Sub, ` t 2 : S 11

Case T-App (continued): t = t 1 t 2 ` t 1 : T 11!T 12 ` t 2 : T 11 T = T 12 Subcase E-AppAbs: t 1 = x:s 11 t 12 t 2 = v 2 t 0 =[x 7! v 2 ]t 12 By the inversion lemma for the typing relation T 11 <: S 11 and, x:s 11 ` t 12 : T 12 By T-Sub, ` t 2 : S 11 By the substitution lemma, ` t 0 : T 12, and we are done ` t 1 : T 11!T 12 ` t 2 : T 11 ` t 1 t 2 : T 12 (T-App) ( x:t 11 t 12 ) v 2! [x 7! v 2 ]t 12 (E-AppAbs)

Inversion old inversion lemma w/o subtyping Lemma: 1 If ` true : R, then R = Bool 2 If ` false : R, then R = Bool 3 If ` if t 1 then t 2 else t 3 : R, then ` t 1 : Bool and ` t 2, t 3 : R 4 If ` x : R, then x:r 2 5 If ` x:t 1 t 2 : R, then R = T 1!R 2 for some R 2 with, x:t 1 ` t 2 : R 2 6 If ` t 1 t 2 : R, then there is some type T 11 such that ` t 1 : T 11!R and ` t 2 : T 11

Inversion Lemma for Typing Lemma: If ` x:s 1 s 2 : T 1!T 2, then T 1 <: S 1 and, x:s 1 ` s 2 : T 2 Proof: Induction on typing derivations

Inversion Lemma for Typing Lemma: If ` x:s 1 s 2 : T 1!T 2, then T 1 <: S 1 and, x:s 1 ` s 2 : T 2 Proof: Induction on typing derivations Case T-Sub: x:s 1 s 2 : U U <: T 1!T 2

Inversion Lemma for Typing Lemma: If ` x:s 1 s 2 : T 1!T 2, then T 1 <: S 1 and, x:s 1 ` s 2 : T 2 Proof: Induction on typing derivations Case T-Sub: x:s 1 s 2 : U U <: T 1!T 2 We want to say By the induction hypothesis, but the IH does not apply (we do not know that U is an arrow type)

Inversion Lemma for Typing Lemma: If ` x:s 1 s 2 : T 1!T 2, then T 1 <: S 1 and, x:s 1 ` s 2 : T 2 Proof: Induction on typing derivations Case T-Sub: x:s 1 s 2 : U U <: T 1!T 2 We want to say By the induction hypothesis, but the IH does not apply (we do not know that U is an arrow type) Need another lemma Lemma: If U <: T 1!T 2, then U has the form U 1!U 2, with T 1 <: U 1 and U 2 <: T 2 (Proof: by induction on subtyping derivations)

Inversion Lemma for Typing Lemma: If ` x:s 1 s 2 : T 1!T 2, then T 1 <: S 1 and, x:s 1 ` s 2 : T 2 Proof: Induction on typing derivations Case T-Sub: x:s 1 s 2 : U U <: T 1!T 2 We want to say By the induction hypothesis, but the IH does not apply (we do not know that U is an arrow type) Need another lemma Lemma: If U <: T 1!T 2, then U has the form U 1!U 2, with T 1 <: U 1 and U 2 <: T 2 (Proof: by induction on subtyping derivations) By this lemma, we know U = U 1!U 2, with T 1 <: U 1 and U 2 <: T 2

Inversion Lemma for Typing Lemma: If ` x:s 1 s 2 : T 1!T 2, then T 1 <: S 1 and, x:s 1 ` s 2 : T 2 Proof: Induction on typing derivations Case T-Sub: x:s 1 s 2 : U U <: T 1!T 2 We want to say By the induction hypothesis, but the IH does not apply (we do not know that U is an arrow type) Need another lemma Lemma: If U <: T 1!T 2, then U has the form U 1!U 2, with T 1 <: U 1 and U 2 <: T 2 (Proof: by induction on subtyping derivations) By this lemma, we know U = U 1!U 2, with T 1 <: U 1 and U 2 <: T 2 The IH now applies, yielding U 1 <: S 1 and, x:s 1 ` s 2 : U 2

Inversion Lemma for Typing Lemma: If ` x:s 1 s 2 : T 1!T 2, then T 1 <: S 1 and, x:s 1 ` s 2 : T 2 Proof: Induction on typing derivations Case T-Sub: x:s 1 s 2 : U U <: T 1!T 2 We want to say By the induction hypothesis, but the IH does not apply (we do not know that U is an arrow type) Need another lemma Lemma: If U <: T 1!T 2, then U has the form U 1!U 2, with T 1 <: U 1 and U 2 <: T 2 (Proof: by induction on subtyping derivations) By this lemma, we know U = U 1!U 2, with T 1 <: U 1 and U 2 <: T 2 The IH now applies, yielding U 1 <: S 1 and, x:s 1 ` s 2 : U 2 From U 1 <: S 1 and T 1 <: U 1, rule S-Trans gives T 1 <: S 1

Inversion Lemma for Typing Lemma: If ` x:s 1 s 2 : T 1!T 2, then T 1 <: S 1 and, x:s 1 ` s 2 : T 2 Proof: Induction on typing derivations Case T-Sub: x:s 1 s 2 : U U <: T 1!T 2 We want to say By the induction hypothesis, but the IH does not apply (we do not know that U is an arrow type) Need another lemma Lemma: If U <: T 1!T 2, then U has the form U 1!U 2, with T 1 <: U 1 and U 2 <: T 2 (Proof: by induction on subtyping derivations) By this lemma, we know U = U 1!U 2, with T 1 <: U 1 and U 2 <: T 2 The IH now applies, yielding U 1 <: S 1 and, x:s 1 ` s 2 : U 2 From U 1 <: S 1 and T 1 <: U 1, rule S-Trans gives T 1 <: S 1 From, x:s 1 ` s 2 : U 2 and U 2 <: T 2, rule T-Sub gives, x:s 1 ` s 2 : T 2, and we are done

Subtyping with Other Features

Ascription and Casting Ordinary ascription: ` t 1 ` t 1 : T as T : T (T-Ascribe) v 1 as T! v 1 (E-Ascribe)

Ascription and Casting Ordinary ascription: (upcasting) ` t 1 ` t 1 : T as T : T (T-Ascribe) v 1 as T! v 1 (E-Ascribe) Casting (cf Java): trust (at compile time) but verify (at run time) (downcasting) ` t 1 ` t 1 : S as T : T (T-Cast) ` v 1 : T v 1 as T! v 1 (E-Cast) does progress theorem still hold?

Subtyping and Variants <l i :T i i21n > <: <l i :T i i21n+k > (S-VariantWidth) for each i S i <: T i <l i :S i i21n > <: <l i :T i i21n > (S-VariantDepth) <k j :S j j21n > is a permutation of <l i :T i i21n > <k j :S j j21n > <: <l i :T i i21n > (S-VariantPerm) ` t 1 : T 1 ` <l 1 =t 1 > : <l 1 :T 1 > (T-Variant)

Subtyping and Lists S 1 <: T 1 List S 1 <: List T 1 (S-List) Ie, List is a covariant type constructor

Subtyping and References S 1 <: T 1 T 1 <: S 1 Ref S 1 <: Ref T 1 (S-Ref) Ie, Ref is not a covariant (nor a contravariant) type constructor Why?

Subtyping and References S 1 <: T 1 T 1 <: S 1 Ref S 1 <: Ref T 1 (S-Ref) Ie, Ref is not a covariant (nor a contravariant) type constructor Why? I When a reference is read, the context expects a T 1, so if S 1 <: T 1 then an S 1 is ok

Subtyping and References S 1 <: T 1 T 1 <: S 1 Ref S 1 <: Ref T 1 (S-Ref) Ie, Ref is not a covariant (nor a contravariant) type constructor Why? I When a reference is read, the context expects a T 1, so if S 1 <: T 1 then an S 1 is ok I When a reference is written, the context provides a T 1 and if the actual type of the reference is Ref S 1, someone else may use the T 1 as an S 1 So we need T 1 <: S 1

Subtyping and Arrays Similarly array is mutable, list is immutable S 1 <: T 1 T 1 <: S 1 Array S 1 <: Array T 1 (S-Array)

Subtyping and Arrays Similarly array is mutable, list is immutable S 1 <: T 1 T 1 <: S 1 Array S 1 <: Array T 1 (S-Array) S 1 <: T 1 Array S 1 <: Array T 1 (S-ArrayJava) This is regarded (even by the Java designers) as a mistake in the design in Java syntax, S1[] <: T1[]

References again Observation: a value of type Ref T can be used in two di erent ways: as a source for values of type T and as a sink for values of type T

References again Observation: a value of type Ref T can be used in two di erent ways: as a source for values of type T and as a sink for values of type T Idea: Split Ref T into three parts: I Source T: reference cell with read cabability I Sink T: reference cell with write cabability I Ref T: cell with both capabilities

Modified Typing Rules ` t 1 : Source T 11 `!t 1 : T 11 (T-Deref) ` t 1 : Sink T 11 ` t 2 : T 11 ` t 1 :=t 2 : Unit (T-Assign)

Subtyping rules S 1 <: T 1 Source S 1 <: Source T 1 (S-Source) T 1 <: S 1 Sink S 1 <: Sink T 1 Ref T 1 <: Source T 1 Ref T 1 <: Sink T 1 (S-Sink) (S-RefSource) (S-RefSink)

Algorithmic Subtyping

Syntax-directed rules In the simply typed lambda-calculus (without subtyping), each rule can be read from bottom to top in a straightforward way ` t 1 : T 11!T 12 ` t 2 : T 11 ` t 1 t 2 : T 12 (T-App) If we are given some and some t of the form t 1 t 2,wecantry to find a type for t by 1 finding (recursively) a type for t 1 2 checking that it has the form T 11!T 12 3 finding (recursively) a type for t 2 4 checking that it is the same as T 11

Technically, the reason this works is that We can divide the positions of the typing relation into input positions ( and t) and output positions (T) I For the input positions, all metavariables appearing in the premises also appear in the conclusion (so we can calculate inputs to the subgoals from the subexpressions of inputs to the main goal) I For the output positions, all metavariables appearing in the conclusions also appear in the premises (so we can calculate outputs from the main goal from the outputs of the subgoals) ` t 1 : T 11!T 12 ` t 2 : T 11 ` t 1 t 2 : T 12 (T-App)

Syntax-directed sets of rules The second important point about the simply typed lambda-calculus is that the set of typing rules is syntax-directed, in the sense that, for every input and t, there one rule that can be used to derive typing statements involving t Eg, if t is an application, then we must proceed by trying to use T-App If we succeed, then we have found a type (indeed, the unique type) for t If it fails, then we know that t is not typable! no backtracking!

Non-syntax-directedness of typing When we extend the system with subtyping, both aspects of syntax-directedness get broken 1 The set of typing rules now includes two rules that can be used to give a type to terms of a given shape (the old one plus T-Sub) ` t : S ` t : T S <: T (T-Sub) 2 Worse yet, the new rule T-Sub itself is not syntax directed: the inputs to the left-hand subgoal are exactly the same as the inputs to the main goal! (Hence, if we translated the typing rules naively into a typechecking function, the case corresponding to T-Sub would cause divergence)

Non-syntax-directedness of subtyping Moreover, the subtyping relation is not syntax directed either 1 There are lots of ways to derive a given subtyping statement 2 The transitivity rule S <: U S <: T U <: T (S-Trans) is badly non-syntax-directed: the premises contain a metavariable (in an input position ) that does not appear at all in the conclusion To implement this rule naively, we d have to guess a value for U!

What to do?

What to do? 1 Observation: We don t need 1000 ways to prove a given typing or subtyping statement one is enough! Think more carefully about the typing and subtyping systems to see where we can get rid of excess flexibility 2 Use the resulting intuitions to formulate new algorithmic (ie, syntax-directed) typing and subtyping relations 3 Prove that the algorithmic relations are the same as the original ones in an appropriate sense

Developing an algorithmic subtyping relation

Subtype relation S <: S S <: U U <: T S <: T (S-Refl) (S-Trans) {l i :T i i21n+k } <: {l i :T i i21n } (S-RcdWidth) for each i S i <: T i {l i :S i i21n } <: {l i :T i i21n } (S-RcdDepth) {k j :S j j21n } is a permutation of {l i :T i i21n } {k j :S j j21n } <: {l i :T i i21n } (S-RcdPerm) T 1 <: S 1 S 2 <: T 2 S 1!S 2 <: T 1!T 2 S <: Top (S-Arrow) (S-Top)

Issues For a given subtyping statement, there are multiple rules that could be used last in a derivation 1 The conclusions of S-RcdWidth, S-RcdDepth, and S-RcdPerm overlap with each other 2 S-Refl and S-Trans overlap with every other rule

Step 1: simplify record subtyping Idea: combine all three record subtyping rules into one macro rule that captures all of their e ects {l i i21n } {k j j21m } k j = l i implies S j <: T i {k j :S j j21m } <: {l i :T i i21n } (S-Rcd)

Simpler subtype relation S <: S S <: U U <: T S <: T (S-Refl) (S-Trans) {l i i21n } {k j j21m } k j = l i implies S j <: T i {k j :S j j21m } <: {l i :T i i21n } (S-Rcd) T 1 <: S 1 S 2 <: T 2 S 1!S 2 <: T 1!T 2 S <: Top (S-Arrow) (S-Top)

Step 2: Get rid of reflexivity Observation: S-Refl is unnecessary Lemma: S <: S can be derived for every type S without using S-Refl

Even simpler subtype relation S <: U S <: T U <: T (S-Trans) {l i i21n } {k j j21m } k j = l i implies S j <: T i {k j :S j j21m } <: {l i :T i i21n } (S-Rcd) T 1 <: S 1 S 2 <: T 2 S 1!S 2 <: T 1!T 2 S <: Top (S-Arrow) (S-Top)

Step 3: Get rid of transitivity Observation: S-Trans is unnecessary Lemma: If S <: T can be derived, then it can be derived without using S-Trans

Algorithmic subtype relation Ì S <: Top (SA-Top) Ì T 1 <: S 1 Ì S 2 <: T 2 Ì S 1!S 2 <: T 1!T 2 (SA-Arrow) {l i i21n } {k j j21m } for each k j = l i, Ì S j <: T i Ì {k j :S j j21m } <: {l i :T i i21n } (SA-Rcd)

Soundness and completeness Theorem: S <: T i Ì S <: T Proof: (Homework) Terminology: I The algorithmic presentation of subtyping is sound with respect to the original if Ì S <: T implies S <: T (Everything validated by the algorithm is actually true) I The algorithmic presentation of subtyping is complete with respect to the original if S <: T implies Ì S <: T (Everything true is validated by the algorithm)

Subtyping Algorithm (pseudo-code) The algorithmic rules can be translated directly into code: subtype(s, T) = if T = Top, then true else if S = S 1!S 2 and T = T 1!T 2 then subtype(t 1, S 1 ) ^ subtype(s 2, T 2 ) else if S = {k j :S j j21m } and T = {l i :T i i21n } then {l i i21n } {k j j21m } ^ for all i 2 1n there is some j 2 1m with k j = l i and subtype(s j, T i ) else false

Decision Procedures Recall: A decision procedure for a relation R U is a total function p from U to {true, false} such that p(u) =true i u 2 R

Decision Procedures Recall: A decision procedure for a relation R U is a total function p from U to {true, false} such that p(u) =true i u 2 R Is our subtype function a decision procedure?

Decision Procedures Recall: A decision procedure for a relation R U is a total function p from U to {true, false} such that p(u) =true i u 2 R Is our subtype function a decision procedure? Since subtype is just an implementation of the algorithmic subtyping rules, we have 1 if subtype(s, T) = true, then Ì S <: T (hence, by soundness of the algorithmic rules, S <: T) 2 if subtype(s, T) = false, then not Ì S <: T (hence, by completeness of the algorithmic rules, not S <: T)

Decision Procedures Recall: A decision procedure for a relation R U is a total function p from U to {true, false} such that p(u) =true i u 2 R Is our subtype function a decision procedure? Since subtype is just an implementation of the algorithmic subtyping rules, we have 1 if subtype(s, T) = true, then Ì S <: T (hence, by soundness of the algorithmic rules, S <: T) 2 if subtype(s, T) = false, then not Ì S <: T (hence, by completeness of the algorithmic rules, not S <: T) Q: What s missing?

Decision Procedures Recall: A decision procedure for a relation R U is a total function p from U to {true, false} such that p(u) =true i u 2 R Is our subtype function a decision procedure? Since subtype is just an implementation of the algorithmic subtyping rules, we have 1 if subtype(s, T) = true, then Ì S <: T (hence, by soundness of the algorithmic rules, S <: T) 2 if subtype(s, T) = false, then not Ì S <: T (hence, by completeness of the algorithmic rules, not S <: T) Q: What s missing? A: How do we know that subtype is a total function?

Decision Procedures Recall: A decision procedure for a relation R U is a total function p from U to {true, false} such that p(u) =true i u 2 R Is our subtype function a decision procedure? Since subtype is just an implementation of the algorithmic subtyping rules, we have 1 if subtype(s, T) = true, then Ì S <: T (hence, by soundness of the algorithmic rules, S <: T) 2 if subtype(s, T) = false, then not Ì S <: T (hence, by completeness of the algorithmic rules, not S <: T) Q: What s missing? A: How do we know that subtype is a total function? Prove it!

Metatheory of Typing

Issue For the typing relation, we have just one problematic rule to deal with: subsumption ` t : S ` t : T S <: T (T-Sub) Where is this rule really needed?

Issue For the typing relation, we have just one problematic rule to deal with: subsumption ` t : S ` t : T S <: T (T-Sub) Where is this rule really needed? For applications Eg, the term ( r:{x:nat} rx) {x=0,y=1} is not typable without using subsumption

Issue For the typing relation, we have just one problematic rule to deal with: subsumption ` t : S ` t : T S <: T (T-Sub) Where is this rule really needed? For applications Eg, the term ( r:{x:nat} rx) {x=0,y=1} is not typable without using subsumption Where else??

Issue For the typing relation, we have just one problematic rule to deal with: subsumption ` t : S ` t : T S <: T (T-Sub) Where is this rule really needed? For applications Eg, the term ( r:{x:nat} rx) {x=0,y=1} is not typable without using subsumption Where else?? Nowhere else! Uses of subsumption to help typecheck applications are the only interesting ones

Example (T-Abs), x:s 1 ` s 2 : S 2 S 2 <: T 2 (T-Sub), x:s 1 ` s 2 : T 2 (T-Abs) ` x:s 1 s 2 : S 1!T 2

Example (T-Abs), x:s 1 ` s 2 : S 2 S 2 <: T 2 (T-Sub), x:s 1 ` s 2 : T 2 (T-Abs) ` x:s 1 s 2 : S 1!T 2, x:s 1 ` s 2 : S 2 (T-Abs) becomes S 1 <: S 1 (S-Refl) S 2 <: T 2 (S-Arrow) ` x:s 1 s 2 : S 1!S 2 S 1!S 2 <: S 1!T 2 (T-Sub) ` x:s 1 s 2 : S 1!T 2

Example (T-App on the left) ` s 1 : S 11!S 12 T 11 <: S 11 S 12 <: T 12 (S-Arrow) S 11!S 12 <: T 11!T 12 (T-Sub) ` s 1 : T 11!T 12 ` s 2 : T 11 (T-App) ` s 1 s 2 : T 12

Example (T-App on the left) ` s 1 : S 11!S 12 T 11 <: S 11 S 12 <: T 12 (S-Arrow) S 11!S 12 <: T 11!T 12 (T-Sub) ` s 1 : T 11!T 12 ` s 2 : T 11 (T-App) ` s 1 : S 11!S 12 ` s 2 : T 11 ` s 1 s 2 : T 12 becomes T 11 <: S 11 (T-Sub) ` s 2 : S 11 (T-App) ` s 1 s 2 : S 12 S 12 <: T 12 (T-Sub) ` s 1 s 2 : T 12

Example (T-App on the right) ` s 2 : T 2 T 2 <: T 11 (T-Sub) ` s 1 : T 11!T 12 ` s 2 : T 11 (T-App) ` s 1 s 2 : T 12

Example (T-App on the right) ` s 2 : T 2 T 2 <: T 11 (T-Sub) ` s 1 : T 11!T 12 ` s 2 : T 11 (T-App) ` s 1 : T 11!T 12 ` s 1 s 2 : T 12 T 2 <: T 11 becomes (S-Refl) T 12 <: T 12 (S-Arrow) T 11!T 12 <: T 2!T 12 (T-Sub) ` s 1 : T 2!T 12 ` s 2 : T 2 (T-App) ` s 1 s 2 : T 12

Example (T-Sub) ` s : S ` s : U S <: U (T-Sub) ` s : T U <: T (T-Sub)

Example (T-Sub) ` s : S ` s : U S <: U (T-Sub) ` s : T U <: T (T-Sub) becomes ` s : S ` s : T S <: U S <: T U <: T (T-Sub) (S-Trans)