Download presentation
Presentation is loading. Please wait.
Published byYuliana Hartono Modified over 5 years ago
1
A Considerate Specification of the Composite Pattern
Alexander J. Summers Sophia Drossopoulou Imperial College London Imperial College London
2
Overview Specification of the Composite pattern
SAVCBS challenge problem last year Invariant protocol based on Middelkoop et. al. 2006 Idea: “Considerate Reasoning” (IWACO 2009) objects are concerned with each others’ invariants Implementation and verification in Boogie2 Encoding the invariant protocol Simplifying the resulting proof obligations Practical handling of quantified formulas
3
The Composite pattern A tree whose nodes preserve properties related to all their descendant leaves. Subtrees may be added directly without first visiting their parents. We ignore subclassing issues for this talk, and treat a single class Composite
4
The Composite pattern suggested as a specification/verification challenge by Mueller, Leavens and Poetzsch-Heffter Various solutions proposed at SACVBS’08 We describe its specification and verification using invariants, adapting approach suggested by Middelkoop et. al. What we’re going to talk about the effect of different connectives on term calculi Write this at the end, when all other slides are done.#
5
The Composite class class Composite int total; Composite parent;
Composite[] components; int count; void addComponent(Composite c); … }
6
The Composite class 7 class Composite int total; Composite parent;
Composite[] components; int count; void addComponent(Composite c); … } 4 3 2 2 2 1
7
The Composite class 7 class Composite int total; Composite parent; Composite[] components; int count; void addComponent(Composite c); … } 4 3 2 2 2 1 The field parent points to the parent node. The fields components and count maintain pointers to all children – i.e., the inverse of parent.
8
The Composite - invariant
2 2 2 1
9
The Composite - invariant
Each node has a value which is the sum of the values of all its descendant leaves. 2 2 2 1
10
The Composite - invariant
Each node has a value which is the sum of the values of all its descendant leaves. 7 2 2 2 1
11
The Composite - invariant
Each node has a value which is the sum of the values of all its descendant leaves. 7 4 2 2 2 1
12
The Composite - invariant
Each node has a value which is the sum of the values of all its descendant leaves. 7 4 3 2 2 2 1
13
The Composite - invariant
Each node has a value which is the sum of the values of all its descendant leaves. P(n) <=> n.total = (lf.total), where lf a leaf under n 7 4 3 2 2 2 1
14
The Composite - invariant
Each node has a value which is the sum of the values of all its descendant leaves. P(n) <=> n.total = (lf.total), where lf a leaf under n 7 4 3 2 2 2 1
15
The Composite - invariant
Each node has a value which is the sum of the values of all its descendant leaves. P(n) <=> n.total = (lf.total), where lf a leaf under n 7 4 3 2 2 2 1 P(n) is a non-local predicate
16
The Composite - invariant - local
Each node has a value which is the sum of the values of all its direct descendants. 2 2 2 1
17
The Composite - invariant - local
Each node has a value which is the sum of the values of all its direct descendants. Q(n) <=> n.total = (n’.total), where n’.parent=this 2 2 2 1
18
The Composite - invariant - local
Each node has a value which is the sum of the values of all its direct descendants. Q(n) <=> n.total = (n’.total), where n’.parent=this 4 2 2 2 1
19
The Composite - invariant - local
Each node has a value which is the sum of the values of all its direct descendants. Q(n) <=> n.total = (n’.total), where n’.parent=this 4 3 2 2 2 1
20
The Composite - invariant - local
Each node has a value which is the sum of the values of all its direct descendants. Q(n) <=> n.total = (n’.total), where n’.parent=this 7 4 3 2 2 2 1
21
Local invariants achieve as much
P(n) n.total = (lf.total), where lf a leaf under n P(n) is non-local Q(n) n.total = (n’.total), where n’.parent=this Q(n) is local P(n) is stronger than Q(n) n. P(n) n. Q(n) We will be using Q(n) as the invariant for n InvTwo: total == 1 + Sum(i=0..count)::components[i].total
22
The Composite - code void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal( c.total ); }
23
The Composite - code void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal( c.total ); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t);
24
The Composite - code this c void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal( c.total ); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this c
25
The Composite - code this c void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal( c.total ); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this c
26
The Composite - code this c void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal( c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this c
27
The Composite - code this void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal( c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this
28
The Composite - code this void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal( c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this
29
The Composite - code this void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal( c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this
30
The Composite - add a subtree
The Composite - code The Composite - add a subtree void addComponent(Composite c) { components[count]=c; count ++; c.parent = this; addToTotal( c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this
31
The Composite - code this void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal(c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this
32
The Composite - code this void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal(c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this
33
The Composite - code this void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal(c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this
34
The Composite - code this void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal(c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this
35
The Composite - code this void addComponent(Composite c) {
components[count]=c; count ++; c.parent = this; addToTotal(c.total); } void addToTotal(int t){ total=total+t; if (parent!=null){ parent.addToTotal(t); this
36
The Composite class - invariant revisited
7 class Composite int total; Composite parent; Composite[] components; int count; } 4 3 2 2 2 1
37
The Composite class - invariant revisited
7 class Composite int total; Composite parent; Composite[] components; int count; } 4 3 2 2 2 1 InvOne: total > 0 && count ≥ 0
38
The Composite class - invariant revisited
7 class Composite int total; Composite parent; Composite[] components; int count; } 4 3 2 2 2 1 InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total
39
The Composite class - invariant revisited
7 class Composite int total; Composite parent; Composite[] components; int count; } 4 3 2 2 2 1 InvThree: i::components[i].parent == this
40
The Composite class - invariant revisited
7 class Composite int total; Composite parent; Composite[] components; int count; } 4 3 2 2 2 1 InvThree: i::components[i].parent == this InvFour: this.parent != null i::this.parent.components[i] == this
41
The Composite class - invariant revisited
7 class Composite int total; Composite parent; Composite[] components; int count; } 4 3 2 2 2 1 InvThree: i::components[i].parent == this InvFour: this.parent != null i::this.parent.components[i] == this Essentially, parent and components are inverses
42
Visible States Semantics
One basic philosophy for multi-object invariants Idea: invariants can be temporarily broken Must be fixed by the end of each method body Must also be fixed before making further calls In simplest form, all invariants hold at these points Many invariant protocols are based on this idea We use a variant based on Middelkoop et. al. First, basic visible states implemented in Boogie2
43
Visible State Semantics in Boogie2
public void addComponent(Composite c) { components[count] = c; count++; c.parent = this; this.addToTotal(c.total); }
44
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; this.addToTotal(c.total); }
45
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; this.addToTotal(c.total); }
46
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; this.addToTotal(c.total); } assume o :: InvOne(o)
47
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; this.addToTotal(c.total); } assume o :: InvOne(o) assume o :: InvTwo(o) assume o :: InvThree(o) assume o :: InvFour(o)
48
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; this.addToTotal(c.total); }
49
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; this.addToTotal(c.total); assert all invariants.. }
50
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; this.addToTotal(c.total); assert all invariants.. } assert o :: InvOne(o) assert o :: InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o)
51
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; this.addToTotal(c.total); assert all invariants.. }
52
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); }
53
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); }
54
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); }
55
Visible State Semantics in Boogie2
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); } But, addToTotal is meant to fix an invariant which is currently broken!
56
Handling “broken” invariants
We need to allow exceptions to visible states rules Want to allow an invariant to be broken for a call Idea: add a specification construct broken Method signatures can declare “broken” invariants: InvTwo(this) need not hold before calling However, must be established by the method end Related to the INC construct of Middelkoop et. al. // broken: InvTwo(this) private void addToTotal() { ...
57
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); }
58
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); }
59
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); } private void addToTotal() { ...
60
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); } // broken: InvTwo(this) private void addToTotal() { ...
61
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); } // broken: InvTwo(this) private void addToTotal() { ...
62
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); } // broken: InvTwo(this) private void addToTotal() { ... assert o :: InvOne(o) assert o :: InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o)
63
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); } // broken: InvTwo(this) private void addToTotal() { ... assert o :: InvOne(o) assert o :: InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o)
64
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all invariants.. this.addToTotal(c.total); } // broken: InvTwo(this) private void addToTotal() { ... assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o)
65
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); assert all invariants.. } assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o)
66
Handling “broken” invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); assert all invariants.. }
67
Problem: Quantifiers in Assertions
Asserting invariants for all objects is excessive Also, leaves a lot of work to the prover
68
Problem: Quantifiers in Assertions
Asserting invariants for all objects is excessive Also, leaves a lot of work to the prover void m() { // code.. }
69
Problem: Quantifiers in Assertions
Asserting invariants for all objects is excessive Also, leaves a lot of work to the prover void m() { // code.. } assume o :: Inv(o)
70
Problem: Quantifiers in Assertions
Asserting invariants for all objects is excessive Also, leaves a lot of work to the prover void m() { // code.. } assume o :: Inv(o) assert o :: Inv(o)
71
Problem: Quantifiers in Assertions
Asserting invariants for all objects is excessive Also, leaves a lot of work to the prover void m() { // code.. } assume o :: Inv(o) assert o :: Inv(o)
72
Problem: Quantifiers in Assertions
Asserting invariants for all objects is excessive Also, leaves a lot of work to the prover void m() { // code.. } assume o :: Inv(o) assert o :: Inv(o)
73
Problem: Quantifiers in Assertions
Asserting invariants for all objects is excessive Also, leaves a lot of work to the prover void m() { // code.. } assume o :: Inv(o) assert o :: Inv(o)
74
Problem: Quantifiers in Assertions
Asserting invariants for all objects is excessive Also, leaves a lot of work to the prover Which assertions trivial, and which require work? void m() { // code.. } assume o :: Inv(o) assert o :: Inv(o)
75
Coop-sets to track invariants
Idea: track which invariants depend on which fields Middelkoop et. al. – each field gets a “coop set” Declares which invariants may be broken by modifying this field Coop sets consist of pairs (I, P), where... I names an invariant which depends on the field P is a predicate describing when this invariant might be broken by modifying the field, in which: this denotes the object whose field is modified o denotes the object whose invariant may be broken
76
Coop-sets to track invariants
77
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0
78
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ...
79
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop:
80
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop:
81
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this)
82
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this)
83
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this)
84
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this), (InvTwo,o==this)
85
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this), (InvTwo,o==this)
86
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this), (InvTwo,o==this)
87
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this), (InvTwo,o==this) // (InvTwo, i :: o.components[i] == this)
88
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this), (InvTwo,o==this) // (InvTwo, i :: o.components[i] == this)
89
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this), (InvTwo,o==this) // (InvTwo, i :: o.components[i] == this) Use the coop-sets to calculate the vulnerable invariants
90
Coop-sets to track invariants
InvOne: total > 0 && count ≥ 0 InvTwo: total == 1 + Sum(i=0..count) :: components[i].total ... private int total; // coop: (InvOne,o==this), (InvTwo,o==this) // (InvTwo, i :: o.components[i] == this) Use the coop-sets to calculate the vulnerable invariants Note: the objects o are not obviously reachable from this
91
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); assert all invariants.. }
92
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); assert all invariants.. }
93
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total);
94
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total);
95
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants
96
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants
97
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private Composite[] components; Vulnerable Invariants
98
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private Composite[] components; // coop: (InvThree,o==this) // (InvFour,o.parent==this) Vulnerable Invariants
99
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private Composite[] components; // coop: (InvThree,o==this) // (InvFour,o.parent==this) Vulnerable Invariants InvThree(this)
100
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private Composite[] components; // coop: (InvThree,o==this) // (InvFour,o.parent==this) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o)
101
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private Composite[] components; // coop: (InvThree,o==this) // (InvFour,o.parent==this) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o) Note: coop wrong
102
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o)
103
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o)
104
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private int count; // coop: (InvOne,o==this) // (InvTwo,o==this) // (InvThree,o==this) // (InvFour,o.parent==this) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o)
105
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private int count; // coop: (InvOne,o==this) // (InvTwo,o==this) // (InvThree,o==this) // (InvFour,o.parent==this) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this)
106
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private int count; // coop: (InvOne,o==this) // (InvTwo,o==this) // (InvThree,o==this) // (InvFour,o.parent==this) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this)
107
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private int count; // coop: (InvOne,o==this) // (InvTwo,o==this) // (InvThree,o==this) // (InvFour,o.parent==this) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvThree(this)
108
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private int count; // coop: (InvOne,o==this) // (InvTwo,o==this) // (InvThree,o==this) // (InvFour,o.parent==this) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvThree(this), o :: o.parent==this InvFour(o)
109
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvThree(this), o :: o.parent==this InvFour(o)
110
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvThree(this), o :: o.parent==this InvFour(o)
111
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvThree(this)
112
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvThree(this)
113
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this)
114
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this)
115
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private Composite parent; // coop: (InvFour,o==this) // (InvThree,(i :: this==o.components[i])) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this)
116
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private Composite parent; // coop: (InvFour,o==this) // (InvThree,(i :: this==o.components[i])) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvFour(c)
117
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); private Composite parent; // coop: (InvFour,o==this) // (InvThree,(i :: this==o.components[i])) Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvFour(c), o :: (i :: c==o.components[i]) InvThree(o)
118
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvFour(c), o :: (i :: c==o.components[i]) InvThree(o)
119
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvFour(c), o :: (i :: c==o.components[i]) InvThree(o)
120
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvTwo(this), InvFour(c), o :: (i :: c==o.components[i]) InvThree(o)
121
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants InvThree(this), o :: o.parent==this InvFour(o), InvOne(this), InvFour(c), o :: (i :: c==o.components[i]) InvThree(o)
122
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants aInvThree(this), ao :: o.parent==this InvFour(o), aInvOne(this), aInvFour(c), ao :: (i :: c==o.components[i]) InvThree(o)
123
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants asInvThree(this), aso :: o.parent==this InvFour(o), asInvOne(this), asInvFour(c), aso :: (i :: c==o.components[i]) InvThree(o)
124
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assInvThree(this), asso :: o.parent==this InvFour(o), assInvOne(this), assInvFour(c), asso :: (i :: c==o.components[i]) InvThree(o)
125
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants asseInvThree(this), asseo :: o.parent==this InvFour(o), asseInvOne(this), asseInvFour(c), asseo :: (i :: c==o.components[i]) InvThree(o)
126
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants asserInvThree(this), assero :: o.parent==this InvFour(o), asserInvOne(this), asserInvFour(c), assero :: (i :: c==o.components[i]) InvThree(o)
127
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assertInvThree(this), asserto :: o.parent==this InvFour(o), assertInvOne(this), assertInvFour(c), asserto :: (i :: c==o.components[i]) InvThree(o)
128
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
129
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert all except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
130
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
131
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o) Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
132
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o) Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
133
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o) Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
134
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o) Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
135
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o) FEWER INVARIANTS ASSERTED Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
136
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o) FEWER INVARIANTS ASSERTED Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
137
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o) Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
138
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o) Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
139
Calculating vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); assert o :: InvOne(o) assert o :: o!=this InvTwo(o) assert o :: InvThree(o) assert o :: InvFour(o) Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
140
Refining vulnerable invariants
InvThree and InvFour express that components and parent are “inverses” If we use this information, we can refine assertions For example: assert o :: (i :: c==o.components[i]) InvThree(o) “those objects which have c in their components” The only possible such object is c.parent : assert (c.parent != null) InvThree(c.parent) This assertion concerns a (single) object to which we have direct field access This reduces the burden of work on the prover
141
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
142
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
143
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); o.parent==this othis.components Vulnerable Invariants assert InvThree(this), assert o :: o.parent==this InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
144
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); o.parent==this othis.components Vulnerable Invariants assert InvThree(this), assert (i :: o==this.components[i]) InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
145
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assert InvThree(this), assert (i :: o==this.components[i]) InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
146
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assert InvThree(this), assert (i :: o==this.components[i]) InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
147
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); co.components c.parent == o Vulnerable Invariants assert InvThree(this), assert (i :: o==this.components[i]) InvFour(o), assert InvOne(this), assert InvFour(c), assert o :: (i :: c==o.components[i]) InvThree(o)
148
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); co.components c.parent == o Vulnerable Invariants assert InvThree(this), assert (i :: o==this.components[i]) InvFour(o), assert InvOne(this), assert InvFour(c), assert (c.parent != null) InvThree(c.parent)
149
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assert InvThree(this), assert (i :: o==this.components[i]) InvFour(o), assert InvOne(this), assert InvFour(c), assert (c.parent != null) InvThree(c.parent)
150
Refining vulnerable invariants
public void addComponent(Composite c) { assume all invariants.. components[count] = c; count++; c.parent = this; assert vulnerable except “broken” invariants.. this.addToTotal(c.total); Vulnerable Invariants assert InvThree(this), assert (i :: o==this.components[i]) InvFour(o), assert InvOne(this), assert InvFour(c), assert (c.parent != null) InvThree(c.parent)
151
Quantifiers in assumptions
Assuming all invariants is logically very powerful However, in practice this can give too much information to the theorem prover assume o :: InvOne(o) .... InvOne(this)
152
Quantifiers in assumptions
Assuming all invariants is logically very powerful However, in practice this can give too much information to the theorem prover assume o :: InvOne(o) .... InvOne(this), InvOne(this.parent)
153
Quantifiers in assumptions
Assuming all invariants is logically very powerful However, in practice this can give too much information to the theorem prover assume o :: InvOne(o) .... InvOne(this), InvOne(this.parent), InvOne(this.parent.parent)... We can use “triggers” on quantified formulas to control when the prover instantiates them Rule: the prover has to “know about” a term which matches the trigger, to be allowed to instantiate
154
Quantifiers in assumptions
Without choosing appropriate triggers, we get looping and unpredictable results Invariant definitions are guarded by triggers: The invariant name, e.g. InvOne(o) Some additional triggers: hint when it might be useful Invariants assumed/asserted in code are also guarded: Only instantiate if the invariant is determined to be relevant at some point in the method body. This can be by explicitly mentioning it, or because its definition is triggered as above. Resulting specification is well-behaved!
155
Results Our specification in Boogie encodes our intended invariant-based argument naturally and precisely The specification verifies (in about 5 seconds) No additional assertions are needed in the code: only those specified by the invariant protocol The calculation of vulnerable invariants from coop-sets could be easily automated The calculation of coop-sets themselves is by hand, but we believe could be partially automated The essential simplification is gained by knowing “inverse” relationships between fields
156
Conclusions and Future Work
Invariant-based approach handles this example Resulting specification is simple, compared with “direct” approaches, and could be automated Simplifications of vulnerable invariants require some extra work The approach extends to other more-complex examples (with cycles etc.). The treatment of invariants we have used does not extend easily to client-provider relationships A combination with other approaches (e.g., ownership) would be more flexible
157
Finally…
158
Any questions? Thank you for listening! What we’re going to talk about
the effect of different connectives on term calculi Write this at the end, when all other slides are done.#
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.