15-312 Recitation #2: Inductive Proofs 2002-09-04 Joshua Dunfield (joshuad@cs) Carnegie Mellon University Something to talk about: subtyping "s <= t" read as "s is a subtype of t" If you think of types as sets, s <= t asserts that the set corresponding to s is a subset of the set corresponding to t. Example: ints and floats -- every integer value is a float (ignoring issues of precision), i.e. the integers are a subset of the floats. So we want int <= float One use for this is to formalize a language in which, given a function f : float -> int one can write f(2), even though 2 is an int, not a real. The coercion to 2.0 is assumed. Since we haven't looked at type systems yet, I can't show you how it fits in to the type system. Int and float ("real" in SML) are well-known. We can also introduce types "even" and "odd" denoting the even and odd integers. Then we want ?: ______ <= int Our judgment is s <= t, where s and t are types. To keep things simple, the only types will be even, odd, int, float, and pairs. t ::= even | odd | int | float | t * t or in rule form: t1 t t2 t ------ ----- ----- ------- ---------- even t odd t int t float t t1 * t2 t (We'll also let s (\sigma) stand for types.) A pair is a subtype of another pair if the components are subtypes. So: int * int <= int * float, float * int <= float * float, but not, for example, int * float float. Yawn... float <= float By (FF) No other subcases are possible. - CASE: D1 by (IF): ... Very similar to above. Lots of other cases and subcases with the axioms, let's do just one more. - [SUB]CASE: D1 by (EI), D2 by (IF) D1 = ----------- (EI) D2 = ------------ (IF) even <= int int <= float Need to show even <= float. even <= float By (EF) Finally we get to the interesting case. Suppose D1 ends in an application of the (*) rule: s1 <= s2 s1' <= s2' D1 = ---------------------- (*) t1=s1*s1', t2=s2*s2' s1 * s1' <= s2 * s2' We look for all the rules in which the left hand side of the conclusion could match s2 * s2'. Fortunately, there is only one, (*). s2 <= s3 s2' <= s3' D2 = ---------------------- (*) t1=s1*s1', t2=s2*s2', t3=s3*s3' s2 * s2' <= s3 * s3' t1=s1*s1', t3=s3*s3': Need to show t1 <= t3, that is, s1*s1' <= s3*s3' If your derivation(s) have premises, the first thing to do is always to apply the IH and see where that gets you. s1 <= s2 Subderivation of D1 s1' <= s2' Subderivation of D1 s2 <= s3 Subderivation of D2 s2' <= s3' Subderivation of D2 ?: To what can we apply the IH here? s1 <= s2 and s2 <= s3 Yields: s1 <= s3 By IH s1' <= s2' and s2' <= s3' Yields: s1' <= s3' By IH Now we can apply the rule (*)! s1 * s1' <= s3 * s3' By (*) That's it. Of course, we've omitted a bunch of cases, but they're all straightforward. * THM (Reflexivity of <=). For all types t, t <= t. * PROOF: By ... what? What do we have? A type t. So, by induction on the structure of t. We can apply the IH to any type smaller than t. (We can also view the grammar t ::= int | float | ... as shorthand for a set of rules: -------- ---------- ... int type float type in which case we would use rule induction, and could apply the IH to any subderivation.) We have one case for each production in the grammar defining types. - CASE: t=even even <= even By (EE) - CASE: t=odd odd <= odd By (OO) - CASE: t=int Similar - CASE: t=float Similar - CASE: t = t1 * t2 As always, start by applying the IH wherever valid! t1 <= t1 By IH (t1 is smaller than t1 * t2) t2 <= t2 By IH (t2 is smaller than t1 * t2) Can now apply (*). t1 * t2 <= t1 * t2 By (*)