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 (*)