Substitution Principle

advertisement
Lecture 14:
Substitution
Principle
CS201j: Engineering Software
University of Virginia
Computer Science
David Evans
http://www.cs.virginia.edu/evans
How do we know if
saying B is a subtype of A
is safe?
Substitution Principle
• If B is a subtype of A, everywhere the code
expects an A, a B can be used instead
For a function f (A), if f satisfies its
specification when passed an
object whose actual type is type A, f also
satisfies its specification when passed an
object whose actual type is B.
16 October 2003
CS 201J Fall 2003
3
What needs to be true?
For a function f (a A), if f satisfies its
specification when passed an object
whose actual type is type A, f also satisfies
its specification when passed an object
whose actual type is B.
public int f (a A, x X) {
return a.m (x);
}
16 October 2003
CS 201J Fall 2003
4
Subtype Condition 1: Signature Rule
We can use a subtype method where a
supertype methods is expected:
– Subtype must implement all of the
supertype methods
– Argument types must not be more restrictive
– Result type must be at least as restrictive
– Subtype method must not throw exceptions
that are not subtypes of exceptions thrown
by supertype
16 October 2003
CS 201J Fall 2003
5
Signature Rule
class A {
public RA m (PA p) ;
}
class B extends A {
public RB m (PB p) ;
}
RB must be a subtype of RA: RB <= RA
PB must be a supertype of PA: PB >= PA
covariant for results, contravariant for parameters
16 October 2003
CS 201J Fall 2003
6
Signature Examples
public class Object {
public boolean equals (Object o) ;
}
public class String extends Object {
public boolean equals (Object o) ;
}
16 October 2003
CS 201J Fall 2003
7
Signature Examples
public class CellSet {
// A set of Cell’s.
public Cell choose ()
throws NoSuchElementException ;
}
public class ConwayCellSet extends CellSet {
// A set of ConwayCell (<= Cell) objects.
public ConwayCell choose ()
Return type can be a subtype (according to substitution
}
principle, not according to Java compiler rules)
16 October 2003
CS 201J Fall 2003
8
Java’s Rule
• Java compiler is stricter than this: doesn’t
allow any variation in types (“novariant”):
– Overriding method must have same return
and parameter types
– Overriding method can throw fewer
exceptions.
16 October 2003
CS 201J Fall 2003
9
What needs to be true?
For a function f (a A), if f satisfies its
specification when passed an object
whose actual type is type A, f also satisfies
its specification when passed an object
whose actual type is B <= A.
public int f (a A, x X) {
// REQUIRES: a is initialized
// EFFECTS: returns a.value * x.value
return a.m (x);
}
16 October 2003
CS 201J Fall 2003
10
Subtype Condition 2: Methods Rule
• Precondition of the subtype method
must be weaker than the precondition of
the supertype method.
mA.pre  mB.pre
• Postcondition of the subtype method
must be stronger than the postcondition
of the supertype method.
mB.post  mA.post
16 October 2003
CS 201J Fall 2003
11
Methods Rule
Example
public int f (a A, x X) {
// REQUIRES: a is initialized
// EFFECTS: returns a.value * x.value
return a.m (x);
}
public class A {
// An A may be initialized or uninitialized.
// An initialized A has an associated int value.
public int m (x X) {
// REQUIRES: this is initialized
}
public class B extends A {
// A B may be initialized or uninitialized.
// A B may be awake or asleep.
// An initialized B has an associated int value.
public int m (x X) {
// REQUIRES: this is initialized and awake
Can’t make the precondition
}
16 October 2003
CS 201J Fall 2003
stronger! The callsite might
not satisfy it.
12
Methods Rule
Example
public int f (a A, x X) {
// REQUIRES: a is initialized
// EFFECTS: returns a.value * x.value
return a.m (x);
}
public class A {
// An A may be initialized or uninitialized.
// An initialized A has an associated int value.
public int m (x X) {
// REQUIRES: this is initialized
}
public class B extends A {
// A B may be initialized or uninitialized.
// A B may be awake or asleep.
// An initialized B has an associated int value.
public int m (x X) {
// REQUIRES: nothing
}
16 October 2003
CS 201J Fall 2003
13
Methods Rule
Example
public int f (a A, x X) {
// REQUIRES: a is initialized
// EFFECTS: returns a.value * x.value
return a.m (x);
}
public class A {
// An A may be initialized or uninitialized.
// An initialized A has an associated int value.
public int m (x X) {
// ENSURES: Returns this.value * x.value
}
public class B extends A {
// A B may be initialized or uninitialized.
// A B may be awake or asleep.
// An initialized B has an associated int value.
public int m (x X) {
// ENSURES: Returns this.value + x.value.
Postcondition must imply
}
16 October 2003
CS 201J Fall 2003
the supertype’s method
postcondition.
14
Methods Rule
Example
public int f (a A, x X) {
// REQUIRES: a is initialized
// EFFECTS: returns a.value * x.value
return a.m (x);
}
public class A {
// An A may be initialized or uninitialized.
// An initialized A has an associated int value.
public int m (x X)
// MODIFIES: this
// ENSURES: Returns this.value * x.value.
//
Makes this initialized.
public class B extends A {
// A B may be initialized or uninitialized.
// A B may be awake or asleep.
// An initialized B has an associated int value.
public int m (x X)
// MODIFIES: this
// ENSURES: Returns this.value * x.value. Makes
//
this initialized and awake.
16 October 2003
CS 201J Fall 2003
15
Subtype Condition 3: Properties
Subtypes must preserve all properties
described in the overview specification
of the supertype.
16 October 2003
CS 201J Fall 2003
16
Properties Example
• B <= A
• If A is an immutable datatype, can B be
mutable?
• If A is a mutable datatype, can B be
immutable?
16 October 2003
CS 201J Fall 2003
17
Substitution Principle Summary
• Signatures: subtype methods must be type correct
in supertype callsites: result is a subtype
(covariant), parameters are supertypes
(contravariant)
• Methods: subtype postconditions must be stronger
than supertype postconditions (covariant); subtype
preconditions must be weaker than supertype
preconditions (contravariant);
• Properties: subtype must preserve all properties
specified in supertype overview
16 October 2003
CS 201J Fall 2003
18
Substitution Principle
…
(in client code)
MysteryType1 mt1;
MysteryType2 mt2;
MysteryType3 mt3;
…
(anything could be here)
mt1 = mt2.m (mt3);
If the Java compiler is happy with this code, which of these are guaranteed
to be true:
a. The apparent type of mt2 is MysteryType2
b. At the last statement, the actual type of mt2 is MysteryType2
c. MysteryType2 has a method named m
d. The MysteryType2.m method takes a parameter of type MysteryType3
e. The MysteryType2.m method returns a subtype of MysteryType1
f. After the last statement, the actual type of mt1 is MysteryType1
16 October 2003
CS 201J Fall 2003
19
…
(in client code)
MysteryType1 mt1;
MysteryType2 mt2;
MysteryType3 mt3;
…
(anything could be here)
mt1 = mt2.m (mt3);
If the Java compiler is happy with this code, which of these are guaranteed
to be true:
a. The apparent type of mt2 is MysteryType2
TRUE: the apparent type is obvious from the declaration.
b. At the last statement, the actual type of mt2 is MysteryType2
FALSE: we only know the actual type <= MysteryType2
c. MysteryType2 has a method named m
TRUE
d. The MysteryType2.m method takes a parameter of type MysteryType3
FALSE: we only know it takes a parameter >= MysteryType3
e. The MysteryType2.m method returns a subtype of MysteryType1
TRUE: the assignment type checking depends on this
f. After the last statement, the actual type of mt1 is MysteryType1
FALSE: we only know that the actual type <= MysteryType1
16 October 2003
CS 201J Fall 2003
20
Subtyping Rules
class A {
public RA m (PA p) ;
}
…
(in client code)
MysteryType1 mt1;
MysteryType2 mt2;
MysteryType3 mt3;
…
mt1 = mt2.m (mt3);
If A is MysteryType2, what do we know about
RA and PA?
RA must be a subtype of MysteryType1:
RA <= MysteryType1
MysteryType3 must be a subtype of PA:
PA >= MysteryType3
16 October 2003
CS 201J Fall 2003
21
Subtyping Rules
…
(in client code)
class A {
MysteryType1 mt1;
public RA m (PA p) ;
MysteryType2 mt2;
}
MysteryType3 mt3;
class B extends A {
…
public RB m (PB a);
mt1 = mt2.m (mt3);
}
If B <= A, what do we know about RB and PB?
RB must be a subtype of RA: RB <= RA
PA must be a subtype of PB: PB >= PA
16 October 2003
CS 201J Fall 2003
22
Substitution Principle
…
(in client code)
class A {
MysteryType1 mt1;
public RA m (PA p) ;
MysteryType2 mt2;
}
MysteryType3 mt3;
class B extends A {
…
public RB m (PB a);
mt1 = mt2.m (mt3);
}
Substitution Principle:
Parameters
PB >= PA
Preconditions
pre_A  pre_B
Result
Postconditions
16 October 2003
RB <= RA
post_B  post_A
CS 201J Fall 2003
23
Substitution Principle
Is this the only way?
16 October 2003
CS 201J Fall 2003
24
Eiffel’s Rules
(Described in Bertrand Meyer paper out today)
16 October 2003
CS 201J Fall 2003
25
Eiffel Rules
The types of the parameters in the
subtype method may be subtypes
of the supertype parameters.
Skier
set_roommate (Skier)
How can Girl override set_roomate?
set_roommate (Girl g)
set_roommate (Boy b)
Boy
Girl
Opposite of substitution principle!
16 October 2003
CS 201J Fall 2003
26
Eiffel and I Can’t Get Up?
Skier
set_roommate (Skier)
Boy
s: skier; g: girl; b: boy;
s := g;
...
s.set_roommate (b);
Girl
set_roomate (Girl)
16 October 2003
CS 201J Fall 2003
27
Meyer’s Excuse
Strangely enough, some workers in the field have
been advocating a contravariant policy. Here it
would mean that if we go for example to class
RANKED_GIRL, where the result of roommate is
naturally redefined to be of type RANKED_GIRL,
we may for the argument of routine share use type
GIRL, or rather scaringly, SKIER of the most
general kind. One type that is never permitted in
this case is RANKED_GIRL! Here is what, under
various mathematical excuses, some professors
have been promoting. No wonder teenage
pregnancies are on the rise.
16 October 2003
CS 201J Fall 2003
28
Substitution Principle / Eiffel
…
(in client code)
class A {
MysteryType1 mt1;
public RA m (PA p) ;
MysteryType2 mt2;
}
MysteryType3 mt3;
class B extends A {
…
public RB m (PB a);
mt1 = mt2.m (mt3);
}
Substitution Principle
Eiffel
Parameters PB >= PA
PB <= PA
Preconditions pre_A  pre_B
pre_B  pre_A
Result
RB <= RA
RB <= RA
Postconditions post_B  post_A post_B  post_A
16 October 2003
CS 201J Fall 2003
29
PS5
• First part (due Thursday Oct 30):
– Questions about subtyping rules
• Which rules make most sense?
• Which rules are most useful for real programs?
– Exercises to learn about concurrency
(Thursday)
– Design a distributed simulation of something
interesting
• Second part (due Nov 11):
– Implement your distributed simulation
16 October 2003
CS 201J Fall 2003
30
Charge
Must it be assumed that because
we are engineers beauty is not
our concern, and that while we
make our constructions robust
and durable we do not also strive
to make them elegant?
Is it not true that the genuine
conditions of strength always
comply with the secret conditions
of harmony?
Gustav Eiffel
16 October 2003
CS 201J Fall 2003
31
Download