invariants for non-hierarchical object structures
DESCRIPTION
Invariants for Non-Hierarchical Object Structures. Ronald Middelkoop, Kees Huizing, Ruurd Kuiper and Erik Luit. Overview. Setting: Sequential Object-Oriented Development Classical Local Invariants Advantages of invariants Non-local Invariants Methods that re-establish an invariant - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/1.jpg)
Invariants for Non-Hierarchical Object Structures
Ronald Middelkoop, Kees Huizing, Ruurd Kuiper and
Erik Luit
![Page 2: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/2.jpg)
2
Ronald Middelkoop
Overview
• Setting: Sequential Object-Oriented Development
• Classical Local Invariants
• Advantages of invariants
• Non-local Invariants
– Methods that re-establish an invariant
– Information Hiding
• Conclusions
![Page 3: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/3.jpg)
3
Ronald Middelkoop
Visible state semantics:After an object’s creation, its invariant I holds in every visible state
Classical Local Invariants
Class C
int i;
C() {…}
int getI() {…}
void setI(int newI) {…}
inv this.i > 2;
Visible state: pre- or post-state of a method execution
![Page 4: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/4.jpg)
4
Ronald Middelkoop
Classical Local Invariants
Theorem:After an object’s creation, its invariant I holds in every visible state, when
• The constructor of that object establishes I• All methods in the program preserve I• No method is called while I is invalid
Class C
int i;
C() {…}
int getI() {…}
void setI(int newI) {…}
inv this.i > 2;
Visible state: pre- or post-state of a method execution
![Page 5: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/5.jpg)
5
Ronald Middelkoop
Classical Local Invariants
Theorem:After an object’s creation, its invariant I holds in every visible state, when
• The constructor of that object establishes I• All methods in the program preserve I• No method is called while I is invalid
Class C
int i;
C() { pre: true; post: true; impl: this.i = 4;}
int getI() {…}
void setI(int newI) {…}
inv this.i > 2;
Visible state: pre- or post-state of a method execution
![Page 6: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/6.jpg)
6
Ronald Middelkoop
Classical Local Invariants
Theorem:After an object’s creation, its invariant I holds in every visible state, when
• The constructor of that object establishes I• All methods in the program preserve I• No method is called while I is invalid
Class C
int i;
C() {…}
int getI() { pre: true; post: result == this.i; impl: return this.i;}
void setI(int newI) {…}
inv this.i > 2;
Visible state: pre- or post-state of a method execution
![Page 7: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/7.jpg)
7
Ronald Middelkoop
Classical Local Invariants
Theorem:After an object’s creation, its invariant I holds in every visible state, when
• The constructor of that object establishes I• All methods in the program preserve I• No method is called while I is invalid
Class C
int i;
C() {…}
int getI() { pre: true; post: result == this.i; impl: return this.i;}
void setI(int newI) { pre: newI > 2; post: this.i == newI; impl: this.i = newI;
}
inv this.i > 2;
Visible state: pre- or post-state of a method execution
![Page 8: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/8.jpg)
8
Ronald Middelkoop
Advantages of Invariants
Class C
int i;
C() {…}
int getI() {…}
void setI(int newI) {…}
inv this.i > 2;
int m() { pre: true; post: result > 4; impl: return this.i +2;}
![Page 9: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/9.jpg)
9
Ronald Middelkoop
Advantages of Invariants
Class C
int i;
C() {…}
int getI() {…}
void setI(int newI) {…}
int m() { pre: true; post: result > 4; impl: return this.i +2;}
m relies on i > 2
![Page 10: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/10.jpg)
10
Ronald Middelkoop
Advantages of Invariants
Class C
int i;
C() {…}
int getI() {…}
void setI(int newI) {…}
int m() { pre: this.i > 2; post: result > 4; impl: return this.i +2;}
m relies on i > 2 m requires i > 2
![Page 11: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/11.jpg)
11
Ronald Middelkoop
Advantages of Invariants
Class C
int i;
C() {…}
int getI() {…}
void setI(int newI) {…}
useC relies on c.i > 2
int m() { pre: this.i > 2; post: result > 4; impl: return this.i +2;}
Class D
int useC() { pre: true; post: result > 4; impl: return this.c.getI() + 2;}
C c;
inv this.c != null;
![Page 12: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/12.jpg)
12
Ronald Middelkoop
Advantages of Invariants
Class C
int i;
C() {…}
int getI() {…}
void setI(int newI) {…}
Class D
int useC() { pre: this.c.i > 2; post: result > 4; impl: return this.c.getI() + 2;}
C c;
useC relies on c.i > 2 useC requires c.i > 2
inv this.c != null;
int m() { pre: this.i > 2; post: result > 4; impl: return this.i +2;}
![Page 13: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/13.jpg)
13
Ronald Middelkoop
Advantages of Invariants
Class D
int useC() { pre: this.c.i > 2; post: result > 4; impl: return this.c.getI() + 2;}
C c;
Class E
int useUseC() { pre: this.d != null; post: result > 8; impl: return this.d.useC() + 4;}
D d;
useUseC calls d.useC() useC requires c.i > 2 useUseC has to establish d.c.i > 2
inv this.c != null;
![Page 14: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/14.jpg)
14
Ronald Middelkoop
Advantages of Invariants
Class D
int useC() { pre: this.c.i > 2; post: result > 4; impl: return this.c.getI() + 2;}
C c;
Class E
int useUseC() { pre: this.d != null this.d.c.i > 2; post: result > 8; impl: return this.d.useC() + 4;}
D d;
useUseC calls d.useC() useC requires c.i > 2 useUseC has to establish d.c.i > 2 useUseC requires d.c.i > 2
inv this.c != null;
![Page 15: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/15.jpg)
15
Ronald Middelkoop
Advantages of Invariants
Class D
int useC() { pre: this.c.i > 2; post: result > 4; impl: return this.c.getI() + 2;}
C c;
Class E
int useUseC() { pre: this.d != null this.d.c.i > 2; post: result > 8; impl: return this.d.useC() + 4;}
D d;
The invariant property propagates throughout the specification
inv this.c != null;
![Page 16: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/16.jpg)
16
Ronald Middelkoop
Advantages of Invariants
Class D
int useC() { pre: this.c.i > 2; post: result > 4; impl: return this.c.getI() + 2;}
C c;
Class E
int useUseC() { pre: this.d != null this.d.c.i > 2; post: result > 8; impl: return this.d.useC() + 4;}
D d;
Advantage 1: Significant reduction in specification overhead
Advantage 2: Re-implementations of a method can rely on a different set of invariants
inv this.c != null;
![Page 17: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/17.jpg)
17
Ronald Middelkoop
Advantages of Invariants
Sufficient:
The verifier of a method M that relies on an invariant I can
– Assume that I holds when M is called
– Deduce if a method M’ that is called by M preserves I
Advantage 1: Significant reduction in specification overhead
Advantage 2: Re-implementations of a method can rely on a different set of invariants
![Page 18: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/18.jpg)
18
Ronald Middelkoop
Non-local Invariants
int d;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;}
CSubject1
Class CSubject Class CObserver
CSubject cs;
CObserver1
CObserver(CSubject toObs) {…}
int getVal() { pre: true; post: return == f(this.cs.d); impl: int i = this.cs.getD();
return f(i); //pseudocode}
inv this.cs != null;
void getD() {…}
![Page 19: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/19.jpg)
19
Ronald Middelkoop
Non-local Invariants
int d;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;}
CSubject1
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver1
CObserver(CSubject toObs) {…}
int getVal() { pre: true; post: return == f(this.cs.d); impl: return this.i;}
inv this.cs != null;
void getD() {…}
![Page 20: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/20.jpg)
20
Ronald Middelkoop
Non-local Invariants
int d;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() { pre: true; post: return == f(this.cs.d); impl: return this.i;}
inv this.i == f(this.cs.d);
inv this.cs != null;
void getD() {…}
• The constructor establishes I• All methods in the program preserve I• No method is called while I is invalid
CObserver X • X.cs ≠ this “invariant of X still holds after assignment”
![Page 21: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/21.jpg)
21
Ronald Middelkoop
inv this.i == f(this.cs.d);
inv this == this.cs.co;
inv this.i == f(this.cs.d);
inv this.cs != null;
Non-local Invariants
int d;
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() { pre: true; post: return == f(this.cs.d); impl: return this.i;}
void getD() {…}
• The constructor establishes I• All methods in the program preserve I• No method is called while I is invalid void update() {
post: this.i == f(this.cs.d);}
CObserver X • X.cs ≠ this “invariant of X still holds after assignment”
CObserver X • X.cs = this this.co = X
![Page 22: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/22.jpg)
22
Ronald Middelkoop
Non-local Invariants
int d;
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() { pre: true; post: return == f(this.cs.d); impl: return this.i;}void getD() {…}
• The constructor establishes I• All methods in the program preserve I• No method is called while I is invalid
void update() { post: this.i == f(this.cs.d);}
inv this.i == f(this.cs.d);
inv this == this.cs.co;
![Page 23: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/23.jpg)
23
Ronald Middelkoop
inv this.i == f(this.cs.d);
inv this == this.cs.co;
Non-local Invariants
int d;
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() { pre: true; post: return == f(this.cs.d); impl: return this.i;}void getD() {…}
• The constructor establishes I• All methods in the program preserve I• No method is called while I is invalid
void update() { inc: this; post: this.i == f(this.cs.d);}
![Page 24: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/24.jpg)
24
Ronald Middelkoop
Theorem:
If, for any invariant I of any object,
– The constructor of that object establishes I
– All methods in the program preserve I
– While I is invalid, any method that is called specifies it doesn’t
rely on I
Then, for any method M, for any invariant I of any allocated object,
– Unless M is the constructor of that object
, I holds when M is called
– When I holds when a method M’ is called by M, I holds when M’
terminates
Theorem:
If, for any invariant I of any object,
– The constructor of that object establishes I
– All methods in the program preserve I
– While I is invalid, any method that is called specifies it doesn’t
rely on I
Then, for any method M, for any invariant I of any allocated object,
– Unless M is the constructor of that object
, I holds when M is called
– I holds when a method M’ called by M terminates
Theorem:
If, for any invariant I of any object,
– The constructor of that object establishes I
– All methods in the program preserve I
– While I is invalid, any method that is called specifies it doesn’t
rely on I
Then, for any method M, for any invariant I of any allocated object,
– or specifies
that it doesn’t rely on I
Theorem:
If, for any invariant I of any object,
– The constructor of that object establishes I
– All methods in the program preserve I
– While I is invalid, no method is called
Then, for any method M, for any invariant I of any allocated
object,
– Unless M is the constructor of that object, I holds when M
is called
– I holds when a method M’ called by M terminates
Theorem:
If, for any invariant I of any object,
– The constructor of that object establishes I
– All methods in the program preserve I
– While I is invalid,
Then, for any method M, for any invariant I of any allocated
object,
– Unless M is the constructor of that object, I holds when M
is called
– I holds when a method M’ called by M terminates
Theorem:
If, for any invariant I of any object,
– The constructor of that object establishes I
– All methods in the program preserve I
– While I is invalid, any method that is called specifies it doesn’t
rely on I
Non-local Invariants with inc
![Page 25: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/25.jpg)
25
Ronald Middelkoop
Non-local Invariants with inc
int d;
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}
void update() { inc: this; post: this.i == f(this.cs.d);}
inv this.i == f(this.cs.d);
inv this == this.cs.co;
![Page 26: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/26.jpg)
26
Ronald Middelkoop
Non-local Invariants with inc
int d;
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}
void update() { inc: this; post: this.i == f(this.cs.d); impl: int d = this.cs.getD();
this.i = f(d);}
inv this.i == f(this.cs.d);
inv this == this.cs.co;
• Update relies on this.cs ≠ null, which follows from this = this.cs.co
![Page 27: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/27.jpg)
27
Ronald Middelkoop
Non-local Invariants with inc
int d;
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}
void update() { inc: this; post: this.i == f(this.cs.d); impl: int d = this.cs.getD();
this.i = f(d);}
• Update relies on this.cs ≠ null, which follows from this = this.cs.co
inv I def this.i == f(this.cs.d);
inv J def this == this.cs.co;
![Page 28: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/28.jpg)
28
Ronald Middelkoop
Non-local Invariants with inc
int d;
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}
void update() { inc: I(this); post: this.i == f(this.cs.d); impl: int d = this.cs.getD();
this.i = f(d);}
• Update relies on this.cs ≠ null, which follows from this = this.cs.co
inv I def this.i == f(this.cs.d);
inv J def this == this.cs.co;
• While I is invalid, any method that is called specifies it doesn’t rely on I
![Page 29: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/29.jpg)
29
Ronald Middelkoop
inv I def this.i == f(this.cs.d);
inv J def this == this.cs.co;
Non-local Invariants with inc
int d;
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() { inc: I(this.co); impl: return this.d;}
void update() { inc: I(this); post: this.i == f(this.cs.d); impl: int d = this.cs.getD();
this.i = f(d);}
• While I is invalid, any method that is called specifies it doesn’t rely on I
![Page 30: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/30.jpg)
30
Ronald Middelkoop
inv I def this.i == f(this.cs.d);
Non-local Invariants with inc
int d;
ONode on;
void setD(int newD) { …}
Class CSubject
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}
void update() {…}
Class ONode
CObserver obs;
ONode next;
inv this.obs != null;
Class CObserver
![Page 31: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/31.jpg)
31
Ronald Middelkoop
Non-local Invariants with inc
int d;
ONode on;
void setD(int newD) { this.d = newD; Onode iter = on; while (iter != null) { iter.obs.update(); iter = iter.next; }}
Class CSubject
void getD() {…}
Class ONode
CObserver obs;
ONode next;
inv this.obs != null;
inv I def this.i == f(this.cs.d);
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void update() {…}
Class CObserver
![Page 32: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/32.jpg)
32
Ronald Middelkoop
inv I def this.i == f(this.cs.d);
inv J def i • this == this.cs.on.nexti.obs;
Non-local Invariants with inc
int d;
ONode on;
void setD(int newD) { this.d = newD; Onode iter = on; while (iter != null) { iter.obs.update(); iter = iter.next; }}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}void update() {…}
Class ONode
CObserver obs;
ONode next;
inv this.obs != null;
![Page 33: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/33.jpg)
33
Ronald Middelkoop
void update() { inc: (CObserver, I, this == inc) post: this.i == f(this.cs.d);}
void update() { inc: (CObserver, I, this.cs == inc.cs) post: this.i == f(this.cs.d);}
void update() { inc: I(this) post: this.i == f(this.cs.d);}
void update() { inc: (CObserver, I, true) post: this.i == f(this.cs.d);}
inv I def this.i == f(this.cs.d);
inv J def i • this == this.cs.on.nexti.obs;
Non-local Invariants with inc
Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
Class ONode
CObserver obs;
ONode next;
inv this.obs != null;
void M(p_1, …,p_n) { inc: (C, I, P), (C’, I’, P’), …}
int d;
ONode on;
void setD(int newD) { this.d = newD; Onode iter = on; while (iter != null) { iter.obs.update(); iter = iter.next; }}
Class CSubject
void getD() {…}
![Page 34: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/34.jpg)
34
Ronald Middelkoop
Information Hiding
Want Subject to work with different kinds of
Observers (simultaneously)
Concrete Observer(s) should be hidden from
Concrete Subject
Then: developing new observers doesn’t affect
the implementation, specification or verification
of the Concrete Subject.
![Page 35: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/35.jpg)
35
Ronald Middelkoop
Information Hiding
inv I def this.i == f(this.cs.d);
inv J def this == this.cs.co;
int d;
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}
void update() { inc: I(this); post: this.i == f(this.cs.d); impl: int d = this.cs.getD();
this.i = f(d);}
Invariant I of CObserver not visible to CSubject
![Page 36: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/36.jpg)
36
Ronald Middelkoop
Information Hiding
inv I def this.i == f(this.cs.d);
inv J def this == this.cs.co;
int d coop I(this.co);
CObserver co;
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CSubject cs;
int i;
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}
void update() { inc: I(this); post: this.i == f(this.cs.d); impl: int d = this.cs.getD();
this.i = f(d);}
Invariant I of CObserver not visible to CSubject
![Page 37: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/37.jpg)
37
Ronald Middelkoop
Information Hiding
inv I def this.i == f(this.cs.d);
inv J def this == this.cs.co;
int d coop I(this.co);
CObserver co coop I(this.co), J(this.co);
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}
void update() { inc: I(this); post: this.i == f(this.cs.d); impl: int d = this.cs.getD();
this.i = f(d);}
CSubject cs coop I(this), J(this);
int i coop I(this);
Invariant I of CObserver not visible to CSubject
![Page 38: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/38.jpg)
38
Ronald Middelkoop
Information Hiding
inv I def this.i == f(this.cs.d);
inv J def this == this.cs.co;
int d coop I(this.co);
CObserver co coop I(this.co), J(this.co);
void setD(int newD) { pre: true; post: this.d == newD; impl: this.d = newD;
if (this.co != null) { this.co.update();}
}
Class CSubject Class CObserver
CObserver(CSubject toObs) {…}
int getVal() {…}
void getD() {…}
void update() { inc: I(this); post: I(this); impl: int d = this.cs.getD();
this.i = f(d);}
CSubject cs coop I(this), J(this);
int i coop I(this);
Invariant I of CObserver not visible to CSubject
![Page 39: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/39.jpg)
39
Ronald Middelkoop
Information Hiding
Observer o coop I(this.o), J(this.o);
Class Subject
…
int d coop I(this.o);
Class CSubject extends Subject
void setD(int newD) { post: this.d == newD; impl: this.d = newD;
if (this.o != null) { this.o.update();}
}
Interface Observer
abstract Subject s coop J(this);
abstract inv I;
inv J def this == this.s.o;
abstract void update() { inc: I(this); post: I(this);}
Class CObserver implements Observer
…
![Page 40: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/40.jpg)
40
Ronald Middelkoop
Information Hiding
Interface Observer
abstract Subject s coop J(this);
abstract inv I;
inv J def this == this.s.o;
abstract void update() { inc: I(this); post: I(this);}
Class CObserver implements Observer
int i coop I(this);
CSubject cs coop I(this);
def s by cs;def I by this.i == f(this.cs.d) J(this);
CObserver(CSubject toObs) {…}
void update() { impl: int d = this.cs.getD();
this.i = f(d);}
![Page 41: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/41.jpg)
41
Ronald Middelkoop
Conclusions• inc allows one to call methods that re-
establish invariants
• coop allows one to make explicit which
invariants might be invalidated when a field is
assigned to
• Together, they allow the full, modular
specification of complex, non-hierarchical
designs like the Observer Pattern
Future Work:
• Complement with other solutions, in particular
hierarchical ones
• Combine with other ways of making
dependencies explicit
![Page 42: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/42.jpg)
50
Ronald Middelkoop
Proof Obligations
{P0} r.f := E; {P1} S2; {P2}
if (b) {
{P3} S3; {P4}
} else {
{P6} S4; {P7}
} {P8}
while (b) {
{P9} S5; {P10}
} {P11}
M() { …
}
int f coop I(r)
int f coop (C,I,P)
int f coop (C, I, dep = r)
![Page 43: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/43.jpg)
51
Ronald Middelkoop
Proof Obligations
{P0’ (X = null P[X/dep])} r.f := E; {P1}
S2; {P2}
if (b) {
{P3} S3; {P4}
} else {
{P6} S4; {P7}
} {P8}
while (b) {
{P9} S5; {P10}
} {P11}
M() { …
}
int f coop I(r)
int f coop (C,I,P)
int f coop (C, I, dep = r)
X represents an arbitrary C-object that the assignment might make inconsistent
![Page 44: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/44.jpg)
52
Ronald Middelkoop
Proof Obligations
{P0’ (X = null P[X/dep])} r.f := E; {P1} S2;
{P2}
if (b) {
{P3} S3; {P4}
} else {
{P6} S4; {P7}
} {P8}
while (b) {
{P9} S5; {P10}
} {P11}
M() { …
}
int f coop I(r)
int f coop (C,I,P)
int f coop (C, I, dep = r)
? P1 I(X) ?
![Page 45: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/45.jpg)
53
Ronald Middelkoop
Proof Obligations
{P0’ (X = null P[X/dep])} r.f := E; {P1} S2; {P2}
if (b) {
{P3} S3; {P4}
} else {
{P6} S4; {P7}
} {P8}
while (b) {
{P9} S5; {P10}
} {P11}
M() { …
}
int f coop I(r)
int f coop (C,I,P)
int f coop (C, I, dep = r)
? S2 Method call ?
![Page 46: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/46.jpg)
54
Ronald Middelkoop
Proof Obligations
{P0’ (X = null P[X/dep])} r.f := E; {P1} S2;
{P2}
if (b) {
{P3} S3; {P4}
} else {
{P6} S4; {P7}
} {P8}
while (b) {
{P9} S5; {P10}
} {P11}
M() { …
}
int f coop I(r)
int f coop (C,I,P)
int f coop (C, I, dep = r)
? P2 I(X) ?
![Page 47: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/47.jpg)
55
Ronald Middelkoop
Proof Obligations
{P0’ (X = null P[X/dep])} r.f := E; {P1} S2;
{P2}
if (b) {
{P3} S3; {P4}
} else {
{P6} S4; {P7}
} {P8}
while (b) {
{P9} S5; {P10}
} {P11}
M() { …
}
int f coop I(r)
int f coop (C,I,P)
int f coop (C, I, dep = r)
Don’t know which branch is taken;Branches might contain calls
![Page 48: Invariants for Non-Hierarchical Object Structures](https://reader035.vdocument.in/reader035/viewer/2022062301/568148f6550346895db6160a/html5/thumbnails/48.jpg)
56
Ronald Middelkoop
Proof Obligations
{P0’ (X = null P[X/dep])} r.f := E; {P1} S2;
{P2}
if (b) {
{P3} S3; {P4}
} else {
{P6} S4; {P7}
} {P8}
while (b) {
{P9} S5; {P10}
} {P11}
M() { …
}
int f coop I(r)
int f coop (C,I,P)
int f coop (C, I, dep = r)
Don’t know if while is executed;Body might contain calls