NumberRepresentedByArray
NumberRepresentedByArray
1 The problem
Problem: Given an array x of digits. Calculate the number represented by the array.
For example, array x = [1, 5, 6, 3, 8] represents the number 15638.
Idea behind the invariant: the invariant expresses the same thing over the interval [0..k − 1]
as the postcondition does over the interval [0..n − 1]. Where k ∈ [0..n] is an auxiliary variable
of the program and if k = n then the two express the same, having Inv and k = n will give
us the postcondition.
Since Inv ∧ k = n =⇒ P ost, choosing k 6= n as the loop condition, the following condition
is satisfied: Inv ∧ ¬π =⇒ P ost
(As due to the invariant k ∈ [0..n], k < n is also a good loop condition.)
The precondition does not imply the invariant. The loop needs a proper initialisation.
Q0 = (P re ∧ s = 0 ∧ k = 0)
To satisfy the condition Q0 =⇒ Inv we choose k as 0, in this case it is easy to provide the
k−1
xn−i · 10i . The sum is empty, its value is zero, so we have to set s to zero
P
value of the sum
i=0
to make Q0 =⇒ Inv true.
1
Theory of Programming Zsolt Borsi
Inv ∧ k 6= n =⇒ n − k > 0
Of course the loop body will increase k until it equals to n. When k = n, the expected sum
is calculated. By increasing k, the value of the variant function has to be decreased. This
is why we choose n − k as the variant function, since when k is approaching n, then the
difference n − k is getting smaller. To preserve the truth of the loop invariant, s has to be
increased by s + x[n − k] · 10k .
s, k := 0, 0
Q0
k 6= n
s, k := s + x[n − k] · 10k , k + 1
3 Second solution
3.1 Synthesis (outline)
We can avoid using exponentiation by expanding the invariant as follows:
k−1
x[n − i] · 10i ∧ k ∈ [0..n] ∧ h = 10k )
P
Inv = (P re ∧ s =
i=0
We introduce variable h:N in order to avoid using exponentiation by storing 10k in h.
The precondition does not imply the invariant. The loop needs a proper initialisation.
In order to satisfy the condition Q0 =⇒ Inv, we choose k as 0. In this case it is easy to
k−1
x[ n − i] · 10i . The sum is empty, its value is zero, so we have
P
provide the value of the sum
i=0
to set s to zero. At the same time, h has to be set to 1 (as h = 10k has to hold according to the
invariant) in order to make Q0 =⇒ Inv true.
Q0 = (P re ∧ s = 0 ∧ k = 0 ∧ h = 1)
Inv ∧ k 6= n =⇒ n − k > 0
Of course the loop body will increase k until it equals to n, when the expected sum is calcu-
lated. By increasing k, the value of the variant function is decreasing. To preserve the truth
of loop invariant s has to be increased by s + x[n − k] · h, and to preserve h = 10k in the
invariant, h has to be multiplied by 10.
s, k, h := 0, 0, 1
Q0
k 6= n
s, h, k := s + x[n − k] · h, 10 · h, k + 1
2
Theory of Programming Zsolt Borsi
4 Third solution
4.1 The specification
A = (x:[0..9]n , s:N)
P re = (x = x0 )
P ost = (P re ∧ s = value(n))
where (
10 · value(k − 1) + x[k] k ∈ [1..n]
value(k) =
0 k=0
1. Let assume variable s stores the value of a number represented by the first k − 1 ele-
ments of array x.
3. . . .
It is an iteration. This suggest that we will need a loop. What is the invariant of the loop?
The rationale behind the following invariant is, that it reflects that s stores the value of the
number represented by the first k − 1 elements of array x:
Inv = (P re ∧ s = value(k − 1) ∧ k ∈ [1..n + 1])
Having Inv and k = n + 1 will give us the postcondition, this is why n + 1 is allowed as a
maximum value of k. The minimal allowed value for k is 1, when we know value(k − 1), it
is value(0) = 0 by the definition of the function.
Q0 = (Q ∧ s = 0 ∧ k = 1)
Since Inv ∧ k = n + 1 ≡ P ost, we get the loop condition k ≤ n.
Inv =⇒ k ≤ n ∨ k > n
t:n+1−k
We prove that our loop body s, k := 10 · s + x[k], k + 1 preserves the invariant and decreases
the value of the variant function.
(Inv ∧ k ≤ n ∧ n + 1 − k = t0 ) =⇒ wp(s, k := 10 · s + x[k], k + 1, Inv ∧ n + 1 − k < t0 )
wp(s, k := 10 · s + x[k], k + 1, Inv ∧ n + 1 − k < t0 ) = (P re ∧ 10 · s + x[k] = value(k) ∧ k + 1 ∈
[1..n + 1] ∧ k ∈ [1..n] ∧ ∧n − k < t0 )
• 10 · s + x[k] = value(k) holds since s = value(k − 1) (by the invariant) and value(k) =
10 · value(k − 1) + x[k] (by the definition of the function value)
3
Theory of Programming Zsolt Borsi
• n − k < t0 holds as n − k + 1 = t0
Notice that we need to guarantee that k ∈ [1..n]. That is, k has to be an index of x (otherwise
the program s, k := 10 · s + x[k], k + 1 aborts).
s, k := 0, 1
Q0
k≤n
s, k := 10 · s + x[k], k + 1