5.3 Reverse Example
6.3.3.1 ADD DEALLOC Macro
1 #define ADD DEALLOC(a, b) 2 {
3 PRE DEALLOC(a); 4 a := copy(b);
5 a_dealloc := true; // Add the Deallocation to ’a’ 6 }
ADD DEALLOC(a, b) macro:
• uses pre-deallocation macro to empty variable a and reset its flag value; • creates a fresh copy of variable b, whose memory space is not aliased
with any existing variable;
• assigns the copied b to variable a and add the flag to a
Assumption 2 For an assignment a := copy(b), we include a precondition
e(a)6= e(b)
to ensure when adealloc and bdealloc are both true, variable a and b are not
aliased to the same memory space before the function call. Also, we need an extra precondition
valid(e(b)) = true
to ensure the memory address pointed by variable b is valid and safe to per- form the operation. With above preconditions, we can ensure adealloc must be
false when variable a and b are aliased and also bdealloc is true. Therefore,
PRE DEALLOC(a) will not free the memory at e(a) = e(b), making e(b) an
invalid address and avoid segmentation fault when trying to copy from e(b).
Theorem 6.4 ADD DEALLOC(a, b) macro makes a copy of variable b and as- signs it to a. If INV ande(a)6= e(b) and valid(e(b)) hold before ADD DEALLOC(a, b) macro, then INV still holds true after the macro, as below Hoare Logic:
{INV ∧ (∀i ∈ V ARS • e(i) = e0(i))∧ (∀d ∈ ADR • valid(d) = v0(d))
∧ e(a) 6= e(b) ∧ valid(e(b))} ADD DEALLOC(a, b)
{INV ∧ (∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) = e0(i))
∧ (∀d ∈ ADR • d 6= e0(a)∧ d 6= e(a) =⇒ valid(d) = v0(d))
98
1 {INV ∧ (∀i ∈ V ARS • e(i) = e0(i))∧ (∀d ∈ ADR • valid(d) = v0(d))∧ 2 e(a)6= e(b) ∧ valid(e(b))}
1
3 PRE_DEALLOC(a);
4 {INV ∧ (∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) = e0(i)) 5 ∧(∀d ∈ ADR • d 6= e0(a) =⇒ valid(d) = v0(d))∧ 6 e0(a)6= e(b) ∧ valid(e(b))}
2
7
8 {INV ∧ valid(e(b)) ∧ (∀i ∈ V ARS • e(i) = e1(i)) 9 ∧(∀d ∈ ADR • valid(d) = v1(d))
3
10 a:=copy(b); 11 a_dealloc:=true;
12 {fresh(a) ∧ (∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) = e1(i))
4a∧
13 (∀d ∈ ADR • d 6= e(a) =⇒ valid(d) = v1(d))
4b∧
14 valid(e(a))∧ valid(e(b)) ∧ e(adealloc)
4c}
15
16 {INV
5a ∧ (∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) = e0(i))
5b∧
17 (∀d ∈ ADR • d 6= e0(a)∧ d 6= e(a) =⇒ valid(d) = v0(d))
5c∧
18 valid(e(b))∧ valid(e(a)) ∧ e(adealloc)}
Listing 6.3: Tableau of ADD DEALLOC(a, b) macro
The previous section shows our invariant is preserved before and after pre- deallocation macro. So we are only required to prove our invariant still holds after the last two code statements, as below:
Assumption 1
e(a)6= e(b) and valid(e(b)) are assumed to be true in the entry condition of the macro.
Reasoning about 2
Show e(b) = e0(a) and valid(e(b)) are both true in
the post condition of pre-deallocation macro (refer to Theorem 6.2).
Because e(b) = e0(b) 6= e0(a) and only validity of e0(a) is changed by
pre-deallocation macro, valid(e(b)) is true in the post-state.
Assumption 3
Define e1(i) and v1(d ) to store the addresses and validity
of variables respectively after PRE DEALLOC macro. In doing so, we can focus on the precondition and post condition of line 10 and 11.
Reasoning about
4a and
4b Show e(i) = e1(i) and valid(d) = v1(i) is
true. Since only e(a) and adealloc is changed by line 10 and 11, e(i) remains
the same as e1(i) for all other variables, and the validity is unchanged for all
Assumption
4c Show valid(e(a)), valid(e(b)), fresh(a) and e(adealloc) are
true in the post-condition.
valid(e(a))∧ fresh(a) is included into the post-state from 6.9.
valide(e(b)) remains true in the post-state because our macro in (line 10 and 11) does not de-allocate anything.
e(adealloc) is true from line 11.
Reasoning about
5a Show that INV holds at the end of macro.
IN V :∀i, j ∈ V ARS • inv dealloc(i, j) A
∧ ∀i ∈ ARRV ARS • inv arr(i) B
Proof. [Reasoning Deallocation Invariant ( A
)]
Let i, j ∈ V ARS be the witness variables. We must show that ∀i, j•inv dealloc(i, j) holds true after ADD DEALLOC(a, b) macro. Consider the following four cases:
• Case 1: i, j includes both a and b
Given i≡ a ∧ j ≡ b (or equivalently j ≡ a ∧ i ≡ b), the invariant can be rewritten as:
inv dealloc(a, b) :(e(adealloc)∧ e(bdealloc)∧
a6≡ b) =⇒ e(a) 6= e(b)
(6.19)
From precondition e0(a) 6= e0(b), which implies a 6≡ b, and fresh(a), we
conclude that a6≡ b =⇒ e(a) 6= e(b). That implies that inv dealloc(a, b) still is true in the post-state.
• Case 2: i, j includes a but NOT b
Given i≡ a ∧ j 6≡ b (or equivalently j ≡ a ∧ i 6≡ b), the invariant can be rewritten as:
inv dealloc(a, j) :e(adealloc)∧ e(jdealloc)∧
a6≡ j =⇒ e(a) 6= e(j)
(6.20)
Assume that all the preconditions in (6.20) are true, including a 6≡ j. With true value of f resh(a) : j 6≡ a =⇒ e(j) 6= (a), we have e(j) 6= e(a) in the post-state and conclude inv dealloc(a, j) is true after the macro.
100 • Case 3: i, j includes b but NOT a
Given i≡ b ∧ j 6≡ a (or equivalently j ≡ b ∧ i 6≡ a), the invariant can be rewritten as:
inv dealloc(b, j) :e(bdealloc)∧ e(jdealloc)∧
b6≡ j =⇒ e(b) 6= e(j)
(6.21)
Because j 6≡ a and only variable a and adealloc are changed so variable j
and jdealloc stay unchanged in post-state.
Since inv dealloc(b, j) was true in the pre-state, we have inv dealloc(b, j) hold true in the post-state.
• Case 4: i, j are both different from a, b
The macro does not change any value of variable i and j , so the invariant inv dealloc(i, j ) still holds.
2
Proof. [Reasoning Array Invariant B
]
We must show ∀i ∈ ARRV ARS • e(idealloc) =⇒ valid(e(i)) holds true in the
post-state.
Let i ∈ ARRV ARS such that e(idealloc) is true in the post-state and we
have to show valid(e(i)). • Case 1: i 6≡ a
We know e(i)6= e(a) because of fresh(a). From inv arr(i) in line 8, we have
∀i ∈ ARRV ARS • e1(idealloc) =⇒ v1(e1(i))
From
4a, we have e(i) = e1(i) because i6≡ a ∧ i 6≡ adealloc.
From
4b, we have valid(e(i)) = v1(e(i)) because e(i)6= e(a)
Therefore, the validity must remain unchanged in the post-state. valid(e(i)) = v1(e(i)) = v1(e1(i))
• Case 2: i ≡ a
inv arr(a) : e(adealloc) =⇒ valid(e(a)) holds true because we have
valid(e(a)) in
4c, which comes from post condition of copy.
2
Reasoning about
5b Show ∀i ∈ V ARS • i 6≡ a ∧ i 6≡ adealloc =⇒ e(i) =
e0(i) is true in the post condition.
Proof. Let i∈ V ARS be a variable such that i 6≡ a and i 6≡ adealloc. We must
show e(i) = e0(i).
From
4a because i6≡ a ∧ i 6≡ adealloc, we have e(i) = e1(i).
From 2
and 3
because i6≡ a ∧ i 6≡ adealloc, we have e0(i) = e1(i).
Therefore, by combining the above conditions i 6≡ a ∧ i 6≡ adealloc, we
conclude e(i) = e0(i).
2
Reasoning about
5c Show ∀d ∈ ADR • d 6= e0(a) ∧ d 6= e(a) =⇒
valid(d) = v0(d) is true in the post condition.
Proof. Let d ∈ ADR be an address such that d 6= e0(a) and d 6= e(a). We
must show valid(d) = v0(d).
From
4b because d6= e(a), we have valid(d) = v1(d).
From 2
and 3
because d6= e0(a), we have v0(d) = v1(d).
Therefore, by combining the above conditions (d 6= e0(a)∧ d 6= e(a)), we
conclude valid(d) = v1(d) = v0(d).
102