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)