Professional Documents
Culture Documents
1
Outline
Invariants
Violating the invariant
Marriage problem
2
Invariants explained in 60 seconds
class
ACCOUNT
feature
balance: INTEGER
invariant
balance >= 0
end
3
Temporary violation
See demo.
4
Public interface of person (without contracts)
class class
PERSON MARRIAGE
feature feature
spouse: PERSON make
-- Spouse of Current. local
alice: PERSON
marry (a_other: PERSON) bob: PERSON
-- Marry `a_other’. do
do create alice
… create bob
end bob.marry (alice)
end end
end
5
Write the contracts
class PERSON
feature
spouse: PERSON
invariant
??
end
6
A possible solution
class PERSON
feature
spouse: PERSON
marry (a_other: PERSON)
require
a_other /= Void
a_other /= Current
a_other.spouse = Void
spouse = Void
ensure
spouse = a_other
a_other.spouse = Current
end
invariant
spouse /= Void implies spouse.spouse = Current
spouse /= Current
end
7
Implementing marry
class PERSON
feature
spouse: PERSON
marry (a_other: PERSON)
require
a_other /= Void
a_other /= Current
a_other.spouse = Void
spouse = Void
do
??
ensure
spouse = a_other
a_other.spouse = Current
end
invariant
spouse /= Void implies spouse.spouse = Current
spouse /= Current
end
8
Implementing marry I
class PERSON
feature
spouse: PERSON
marry (a_other: PERSON)
require
a_other /= Void
a_other /= Current
a_other.spouse = Void
spouse = Void Compiler Error:
do
a_other.spouse := Current No assigner
spouse := a_other command for
ensure
spouse = a_other a_other
a_other.spouse = Current
end
invariant
spouse /= Void implies spouse.spouse = Current
spouse /= Current
end
9
Implementing marry II
class PERSON
feature
spouse: PERSON
marry (a_other: PERSON)
require
a_other /= Void and a_other /= Current local
a_other.spouse = Void bob, alice: PERSON
spouse = Void
do do
a_other.set_spouse (Current)
spouse := a_other create bob; create alice
ensure bob.marry (alice)
spouse = a_other
a_other.spouse = Current bob.set_spouse (Void)
end
-- What about the
set_spouse (a_person: PERSON) invariants
do
spouse := a_person -- of bob and alice?
end end
invariant
spouse /= Void implies spouse.spouse = Current
spouse /= Current
end
10
Implementing marry III
class PERSON
feature
spouse: PERSON
marry (a_other: PERSON)
require
a_other /= Void and a_other /= Current
a_other.spouse = Void
spouse = Void
do
a_other.set_spouse (Current)
spouse := a_other What about the
ensure
spouse = a_other invariant of a_other
a_other.spouse = Current in feature marry?
end
feature {PERSON}
set_spouse (a_person: PERSON)
do
spouse := a_person
end
invariant
spouse /= Void implies spouse.spouse = Current
spouse /= Current
end
11
Implementing marry : final version
class PERSON
feature
spouse: PERSON
marry (a_other: PERSON)
require
a_other /= Void
a_other.spouse = Void
spouse = Void
do
spouse := a_other
a_other.set_spouse (Current)
ensure
spouse = a_other
a_other.spouse = Current
end
feature {PERSON}
set_spouse (a_person: PERSON)
do
spouse := a_person
end
invariant
spouse /= Void implies spouse.spouse = Current
spouse /= Current
end
12
Ending the marriage
class PERSON
feature
spouse: PERSON
divorce
require
spouse /= Void Is the order of
do instructions in
spouse.set_spouse (Void) divorce important
spouse := Void for the invariant?
ensure
spouse = Void
(old spouse).spouse = Void
end
invariant
spouse /= Void implies spouse.spouse = Current
spouse /= Current
end
13
What we have seen