Title: Typing
1Typing
- A Behavioral Notion of Subtyping
- By Barbara Liskov and Jeannette M. Wing
- in
- ACM Trans. Of Prog. Languages and Systems
- Vol 16, No 6, November 1994, Pages 1811-1843
2Hierarchy and Inheritance
- Type A is a subtype of B What does this mean?
- Subtypes must provide expected methods with
compatible signatures. - Objects of a subtype ought to behave the same as
their super-types. - Eg x T E should be legal provided that (type
of ) E is a subtype of (the type of) T
3What Ensures Stated Expectations?
- Answer Invariants, called subtype requirement
- Subtype Requirement
- Let f(x) be a predicate about object x of type T.
- Then f(y) should be true for objects of type S
where - S is a subtype of T
- Notation
- f(x), x S, yT, S lt T This is called a typing
judgment - f(y) - An axiom, if you will, in
proof - about types
4Where are these Issues Important?
- In programming languages
- In using inheritance properly
- In type checking
- In using types to catch (and report) errors
- In object oriented design
- In reuse common reusable design patterns
- We need to ensure the correctness of reusable
components. - In promoting common properties to supertypes
- Application Meta Models
5What Should we be looking for in this Paper?
- We design using UML, hence properties
- Drawn using UML
- Stated in OCL
- Do we use/assume Liskov Inheritance
- If so where?
- Are we aware of the assumption? Do our designs
violate them? - Meta Model
- When we inherit form the meta-model why should
our modeling elements have the same behavior?
6Back to LiskovWing Assumptions about properties
- They are formulas
- Is this true in UML? If not what should we do
about them? - Are there pictorial formulas in UML? Do they
satisfy subtype requirement? - How about typing judgments?
- Are there pictorial typing judgments?
- Are properties about state expressible in OCL?
- All ? Some? None? Can we make an adequacy argument
7Back to LiskovWing Assumptions about properties
- Formulas are invariants over
- Single states (to be defined shortly)
- History properties over state transitions
- Properties limited to safety (that is nothing bad
happens) - Is that enough for UML?
8Back to LiskovWing Properties not Considered
- Liveliness properties (that is something good
happens) - Is the OCL action clause a safety property or a
liveliness property? - How about constraints preventing two instances of
the same object having the same state? - Constraints that span across many states
9Back to LiskovWing Properties not Considered
- Producer-Consumer
- Only one producer only one consumer
- Feature Models
- Disjoint features
10Back to LiskovWing Other Questions
- In the UML all meat-models are classes. Hence
subtyping applies to - Sequence diagrams
- Statecharts
- Use Cases
- What subtyping principles have been used
- What inter-diagram consistency principles are
necessary for view integration?
11Models
- Models uses Environments, Stores, States and
computation sequences. - Env Var -gt Obj.
- Store Obj -gt Val.
- State Env X Store.
- Computation sequence
- r1 Tr1 r1 rn-1 Trn rn where.
- Each ri is a state, and.
- Each Tri is a partial function on states.
12More Notation!
- History
- A subsequence of states in any computation.
- Methods come in three main categories
- Constructor returns values of same type.
- Observer does not change the value.
- Mutator Can change the value.
- Can have mixed methods.
- Objects come into existence and get their initial
values through Creators. These are class methods. - Assumption No objects are destroyed. Where is it
used in Liskovs paper?
13Specifying Types
- Types name
- (disc of the) value space
- Per each method
- Name
- Signature
- Including exceptions
- Behavior
- Pre-conditions
- Post-conditions
- Note no creators
- bag type
- uses Bbag(bag for B)
- for all bbag lt- parameters
- putproc(iint)
- requires bpre.elements ltbpre.bound
- modifies b
- ensures bpost.elmsbpre.elmsUi
bpost.boundbpre.bound
14Specifications
- Modifies
- Means no others are modified
- Can have signals specified
- getproc() returns(int) signals(empty)
- modifies b
- ensures if bpre.elms then signal empty
- else bpost.elmsb.pre.elms-result
- result e bpre.elms bpost.bound-bpre.bound
15Specifications
- Post condition modifies ensures
- Specifying Creators
- bag_create proc(nint) returns(bag)
- requires ngt0
- ensures new(result) resultpost(,100)
- bag_create_singleproc(iint) returns(bag)
- ensures new(result) resultpost(i,100)
16Ensuring the Validity of Invariants
- Data Type Induction.
- Make sure that they are valid when object is
created. - Show that if the invariant was valid before a
call to a method, then it is valid after the
call. - Therefore, by induction, they are valid through
any computation sequence.
17Validity of Invariants
- For the Bag example, we need to show that.
- number of elements lt bound of the bag.
- Invariant br.elmts lt br.bound.
- Technically we need to ensure that.
- ?xt t.x e dom(r) gt f(xr).
- This says that the invariant is true in any state
of any computation sequence.
18Validity of Invariants Contd.
- In order to do so, we require that invariants are
established at creation. - That is technically stated as.
- For each creator of type t.
- ?xt t.x I(resultpost/xr).
- This says that the invariant is true in any
state at which the creator is called.
19Subtypes
- Subtypes value space may be different from the
super types value space. - Therefore, to relate values of the subtype to
those of the super-type, there needs to be an
abstraction function. - A subtype specification must say what are its
super types. - We use a subtype clause for this purpose.
20Example Type BStack
- stacktype
- uses BStack(stack for S)
- Invariant length(sr.items) lt spre.limit
- pushproc(iint)
- requires spre.items /
- modifies s
- ensures spost.itemsspre.items i
- spost.limitspre.limit
- Notation is concatenation and is the empty
sequence
21Bstack Continued
- Subtype of bag push for put pop for get height
for card - ?stS A(st)ltmk_elems(st.items),st.limitgt
- where mk_elems Seq -gt M
- ?IInt, sqSeq
- mk_elems()
- mk_elems(sqi)mk_elems(sq)Ui
- Abstraction Function A() maps elements of
subtype to elements of the super type.
22First Definition Constraint Rules
- lt s(Os,S,M) is a subtype of t (Or,T,N) if
there is - an abstraction function A S gt T and
- A renaming function R M gt N
- satisfying the following
- 1. It respects invariants
- ?sS Is(s) gt Ir(A(s))
23First Definition Continuation-1
- 2. Subtype methods preserve super type methods
behavior ( s subtype of t ). - If ms of s is renamed to mt of t then the
following must hold (2.1 Signature Rule). - ms and mt must have the same of arguments.
- If the list of argument types of ms is ai, and
that of mt is bi, then ai gt bi for all i.
(contravariance). - B. Either both ms and mt must return results or
neither does. If there is a result of ms and mt
are a and b respectively, then b gt a.
(covariance). - C. Exceptions of ms are contained in those of mt.
24Covariance and Contravariance
25First Definition Continuation-2
- 2.1 Methods Rule.
- Pre-Conditions
- mt.preA(xpre)/ xpregtms.pre
- That means, any precondition holding for the
super type must hold for the subtype. - Post-Conditions
- ms.post gt mt.postA(xpre)/ xpre, A(xpost)/
xpost. - That means, any post condition holding for the
sub type must hold for the super type.
26First Definition Continuation-3
- 3. Subtype constraints ensure super type
constraints - Constraint Rule
- For all computations C and all states r and f
such that r precedes f in C, - Csxr, xfgt CtA(xr)/ xr, A(xf)/xf
-
27Applying the Subtype Definition
- Back to Stack lt Bag Example.
- s(Ostack,S,push,pop,swap_top,height,equal).
- r(Obag,B,put,get,card,equal).
- Recall
- Bags value is a pair (elements, bound).
- Stacks value is a pair (items, limit).
- Assume (can be proved that) each specification
preserves constraints.
28Application Stack lt Bag Example
- Abstraction function
- A(st) (mk_elems(st.item),st.limit).
- maps a stack element to a bag element, where
mk_elms is recursively defined as follows - mk_elems() .
- mk_elems(sq i) mkelems(sq) U i.
- Can show that function A respects invariants by
induction of the length of sq.
29Application Stack lt Bag Example
- Renaming function
- R(push) put
- R(pop) get
- R(height) card
- R(equal)equal
- Unmapped additional method in the subtype is
swap_top -
30Application Stack lt Bag Example
- Need to show the correspondences between domain
and range methods of R. - Example push and put.
- Precondition Rule Requires us to prove.
- A(Spre).elms lt A(Spre).bound Implies.
- Length(Spre.items) lt Spre.limit.
- Why is this true?
- We will argue this informally.
31Application Stack lt Bag Example
- To show that A(Spre).elms lt A(Spre).bound
Implies Length(Spre.items) lt Spre.limit. - Why is this true?
- Length of the sequence Spre size of the
multiset A(Spre).elms, as A maps the stacks
sequence component to bags multisets by making
each element in the stack go into an element of
the bag. - A (Limit of the Stack) -gt (bound of the bag).
Hence Spre.limit A(Spre).bound. - puts precondition implies A(Spre).elms lt
A(Spre).bound. - Now substitute equals to equals and get the
result.
32Informal Justification of the Definition
- How does this definition guarantee that the
subtypes behavior is similar to the super type?
- Hence can call a subtype method instead of a
super-type method
33Informal Justification of the Definition
- Preservation of Invariants and history
properties. - We can show that rules ensure that any
proposition true about the super type is true
about the subtype. - Like a soundness rule in proofs.
- Values
- Covariance of returned values.
- Contravariance of the inputs.
- Guarantee that a calling a subtype method does
not result in a type violation of the
caller-calee relationship.
34Review Covariance and Contravariance
35Extension Maps
- Recall that for the constraint approach to work,
we must - Add all required constraints as predicates.
- Prove that subtype constraints ensure super type
constraint modulo the abstraction map. - Disadvantage Loss of the history rule
- mt.pre mt.post gt f(xpre/xr, xpost/xp).
- f (xr,xp).
36History Rule
- We prefer to argue inductively as follows
- For every proposition f,
- If f holds after constructors are called
- If f holds in state r, then f holds in state s
after r. - Then f must hold.
- History rule is the above (general) inductive
argument! - Using this rule, we may prove a property f for a
type r that may not hold for a subtype of r. - Consequence must specify enough constraints so
that all necessary properties can be derived from
these constraints.
37Subtypes using Extension Maps
- Invariance Rule (that abstraction respects
invariants) same as constraint based approach - \/s S It(s) gt Is(s)
- Signature Rules
- Contravariance of arguments (stays the same)
- Covariance of results (stays the same)
- Method Rules
- Precondition rules strengthened to equality
- mr.preA(xpre)/xpre ms.pre
- Post-condition rule stays the same
38Extension Map
- E Os x M x Obj -gt Prog must be defined for each
method m not in the domain dom(R). - For each m, and xs, the following conditions
must be true for p, the program to which E(x,m,a)
maps - Inputs to p is the sequence xa.
- The set of methods invoked in p is contained in
the union of dom(R). - The diamond rule must hold.
39The Diamond Rule
- Relate the abstracted values of x at the end of
either calling m - A(xr2)
- Calling the program p
- A(Xy)
- Need
- A(xr2) A(Xy)
40Explanation of the Extension Map
- Purpose
- Running the extra method is similar to running
the explanation program. - Diamond diagram says
- Values returned by running the extra methods in
the subtype is the same. - Note
- The extension rule constrain only what the
explanation program does to the methods object
and not to other objects!
41Explanation of the Extension Map
- Note
- The explanation program does not really run! Its
sole purpose is to show what can happen to the
object. - In reality, the values do not have to be equal,
but observably indistinguishable! (through some
bi-simulation relation). - Now the history rule is restored by combining the
method rules and the extension rule.
42Extension Map Applied to the Bag/Stack Example
- Bag Super type
- uses BBag(bag for B)
- Methods
- put, get, card, equal
- Stack Sub type
- uses BStack(stack S)
- Methods
- push, pop, height, equal,
- swap_top
- E(s.swap_top(i)) s.pop()s.push(i)
43Informal Justification of the Extension Map Method
- What we need to show is the subtype requirement.
That is the following - If -- l(x), x S, S lt T, y T
- then -- l(y)
- What proof rules are allowed?
- Invariants,
- covariance of inputs,
- contravariance of outputs and post conditions
- Equality of pre-conditions
- History rule
44Informal Justification of the Extension Map Method
- Consider any property l of objects for which
there is a proof of l(x) for x S. We will go
through the proof tree of l(x) and show that is
can be transformed in to a proof tree for the
proposition l(y) for y T. - Where is the difficulty ?
- Assumptions in the proof tree of l(x) are at the
leaves of the tree - Can each one be transformed in to an assumption
valid for the subtype T ? (discuss induction
here!). - Can application of proof rules be transformed
into valid proof rules?
45Informal Justification of the Extension Map
Method Contd.
- One of the proof rules used is the history rule,
that reads as - mt.pre mt.post gt f(xpre/xr, xpost/xp)
- f
- Now suppose that the antecedent of this rule has
been proved for the super type. How do we prove
it for the sub type?
46Informal Justification Contd.
- That is we need to show that any (history)
property f satisfies the following - ms.pre /\ ms.post gt fA(xr)/xr,A(xy)/xy.
- Assuming that the following is true for the super
type t. - mt.pre /\ mt.post gt fA(xr)/xr,A(xy)/xy.
47Proof Continued
- ms.pre /\ ms.post gt mt.pre A(xr)/xr /\
- mt.post A(xr)xr, A(xy)/xy
- Follows from the method rules (i.e. equality of
the precondition and contravariance of the post
condition) - Because the formula is proved for the super type,
we get - mt.pre A(xr)/xr /\ mt.postA(xr)/xr,A(xy)/xy
- gt fA(xr)/xr,A(xy)/xy
48Type Hierarchies
- Concern
- Are Liskov/Wing sub-typing rules too strong?
- That is, do they include or exclude many
applications of subtypes ? - We consider two common ways of constructing
subtypes - Extension subtypes
- Constrained subtypes
49Extension Subtypes
- Two non-exclusive ways of having extension
subtypes - Have more methods than the super type.
- Method mapping may not be one-to-one.
- Have more state than the super type.
- Abstraction function is many-to-one.
- If a subtype object is used as a super type
object (should be possible), then the super-type
methods cannot distinguish finer details about
subtype state.
50Extension Subtypes Contd.
- Example 1 Sets of Integers.
- Super type has insert, delete, select, size.
- Subtype has union, intersection in addition.
- No extra state, only methods.
- Extension map method has to explain each
additional method in terms of insert, delete and
select methods. - Need to do similar work if we were to implement
union and intersection using insert, delete and
select.
51Extension Subtypes Contd.-II
- If using constraints, must show that subtypes
constraints imply super types constraints. - What constraints can we impose?
- Bound of the set is invariant. How do we state
this ? - boundr boundy for states r lt y.
52Example II More State in Subtype
- Immutable pairs
- Methods
- fetchFirst, fetchLast
- Immutable Triples
- Extra methods
- fetchMiddle
- Semi-mutable triples
- Extra methods
- fetchMiddle
- replaceMiddle
53Extension Subtypes Contd.
- Immutable types have mutable subtypes provided
that mutations are invisible to the super type - Subtype has more state than the super type.
Hence, abstraction map is many-to-one. Notice - Super type states are equivalence classes over
subtype classes
54Observerbility and Subtyping
- Equality methods Call x.equal(y).
- pair_equal proc (p pair) returns (bool).
- ensures result (p.firstq.first /\
p.secondq.second). - triple_equal proc (p pair) returns (bool).
- ensures result (p.firstq.first /\
p.secondq.second. - /\ p.thirdq.third).
- The difficulty arises when the equal method is
called on subtype object.
55Observability Cont.
- Any method call that expose the abstract state of
a method can run into trouble. - Example Suppose pairs and triples are
implemented as arrays, and the unparse method
must give the components. - The unparse method for the super type must give
only two components ie. - X.unparse returns (x1, x2) in the supertype.
- X.unparse returns (x1, x2,x3) in the subtype.
56Constrained Subtypes
- Subtype more constrained than the super type.
- Abstraction mapping is usually in-to.
57Constrained Subtypes
- One way to constrain bags is by constraining the
bound. - Other ways of constraining bags is to remove the
non-determinism in get and put methods. By
constraining these, we get. - Sequences, queues, stacks.
- What would be a constraint on bags that the
bound is fixed (note not an invariant). - Hence a bag that changes its bound (variable bag)
would not be a subtype of bag. - Virtual Types Only collects common features of
subtypes. They dont exist.
58Comparing Subtype Definitions
- Constraints
- Simple, all history properties that need
preservation need to be explicitly stated - Method and specifications and constraints have to
be consistent (sometime redundant) - Example
- put proc(n int)
- requires bpre.elements lt bpre.bound
- modifies b
- ensures bpre.bound bpost.bound /\ Blah Blah
Blah
59Comparing Subtype Definitions
- Need to graduate common properties from method
specifications to constraints. - Thereby allow common properties of type families
to be stated directly. - In the explanation based approach, sometimes must
put some extra methods to prevent history
properties not holding for subtypes holding for
super types.
60Comparison Continued
- Change_bound proc(nint)
- requires n gt bpre.elems
- modifies b
- ensures bpost.elemsbpre.elems
- /\ bpost.boundn
If the above method did not exist in varyingBag,
then in the extension map based method, we can
deduce that the bound does not change by using
the history rule
61Comparison Continued
- Disadvantage of the constraint based approach.
- Because the history rule is absent, must specify
all constraints carefully. - Loss of the history rule.
- If used history rule would prove properties that
do not hold for subtypes. - Explanation based approach is more operational.
- Useful if subtype only adds more methods.