Professional Documents
Culture Documents
Block 7
Jorge A. Pérez
(based on slides by Arnold Meijster)
2 / 27
2D Counting: Preview
I Problem: Deduce correct programs for counting certain
elements of a given matrix (which represents a 2D function)
I Given an n m matrix, the general case requires an iterative
program that performs n m comparisons.
For instance, counting occurrences of 4:
2 7 4 13 3
6 2 1 19 4
11 8 0 17 5
4 7 9 10 4
2 / 27
2D Counting: Preview
I Problem: Deduce correct programs for counting certain
elements of a given matrix (which represents a 2D function)
I Given an n m matrix, the general case requires an iterative
program that performs n m comparisons.
For instance, counting occurrences of 4:
2 7 4 13 3
6 2 1 19 4
11 8 0 17 5
4 7 9 10 4
I When the entries in the matrix are ordered (thanks to
monotonicity assumptions), we need many less comparisons
2 / 27
2D Counting: Preview
I Problem: Deduce correct programs for counting certain
elements of a given matrix (which represents a 2D function)
I Given an n m matrix, the general case requires an iterative
program that performs n m comparisons.
I When the entries in the matrix are ordered (thanks to
monotonicity assumptions), we need many less comparisons:
0 2 4 7 10
1 2 4 8 11
2 3 5 9 13
4 4 6 17 19
2 / 27
2D Counting: Preview
2 / 27
2D Counting: Preview
2 / 27
2D Counting: Preview
2 / 27
Monotonic functions
3 / 27
Monotonic functions
I descending ( / ): if 8i j 2 V : (i j ) f (i ) f (j ))
;
I decreasing ( / ): if 8i j 2 V : (i j ) f (i ) f (j ))
< > ; < >
3 / 27
Outline
4 / 27
Two dimensional (2D) counting
:[ ) [ )
I Let h 0::m 0::n ! N be a two-dimensional function.
( )
I One can think of h as a landscape, where h x ; y denotes the
( )
altitude at location x ; y .
I Problem: Counting the number of grid points whose altitude
stands below a value w .
5 / 27
Two dimensional (2D) counting
:[ ) [ )
I Let h 0::m 0::n ! N be a two-dimensional function.
( )
I One can think of h as a landscape, where h x ; y denotes the
(
altitude at location x ; y . )
I Problem: Counting the number of grid points whose altitude
stands below a value w .
=
I For the following grid and w 20, we wish to establish z 70. =
1 16 25 22 0 1 17 20 19 29
9 22 7 1 5 16 13 3 14 24
12 6 13 16 14 20 9 14 11 6
16 0 2 13 8 2 16 14 3 16
25 16 20 27 7 3 5 27 24 22
23 23 2 29 14 26 26 14 8 19
25 19 9 18 29 20 27 15 8 18
27 20 27 12 21 1 14 12 6 26
16 7 8 12 3 16 15 15 18 0
13 2 11 29 9 23 15 24 7 12
5 / 27
Two dimensional (2D) counting
:[ ) [ )
I Let h 0::m 0::n ! N be a two-dimensional function.
(
I One can think of h as a landscape, where h x ; y denotes the )
(
altitude at location x ; y . )
I We address the problem of counting the number of grid points
whose altitude stands below a value w .
:
const m ; n ; w N;
:
var z Z;
: =# ( )
fP Z f i ; j j i ; j : 0i < m ^ 0j < n ^ h (i j )
; < wg g
T ;
: =
fQ Z z g
6 / 27
Two dimensional (2D) counting
Exercise 9.1 asks you to confirm that the program fragment satisfies the
specification:
:
const m ; n ; w N;
:
var x ; y ; z Z;
: =# ( )
fP Z f i ; j j i ; j 0 i: < m ^ 0j < n ^ h (i j )
; < wg g
x := ;0
y := ;0
z := ;0
while y < n do
if x < m then
z := + (( )
z ord h x ; y < w );
x := + ;
x 1
else
x := ;
0
y := + ;
y 1
end ;
end ;
:
fQ Z z g =
7 / 27
2D counting on monotonic functions
:[ ) [ )
I Let h 0::m 0::n ! N be a two-dimensional function, but
now ascending ( = ) in both its arguments:
8 / 27
2D counting on monotonic functions
:[ ) [ )
I Let h 0::m 0::n ! N be a two-dimensional function, but
now ascending ( = ) in both its arguments:
x0 x1 ) h ( x0 y ) h ( x1 y )
; ;
y0 y1 ) h ( x y0 ) h ( x y1 )
; ;
8 / 27
2D counting on monotonic functions
:[ ) [ )
I Let h 0::m 0::n ! N be a two-dimensional function, but
now ascending ( = ) in both its arguments:
x0 x1 ) h ( x0 y ) h ( x1 y )
; ;
y0 y1 ) h ( x y0 ) h ( x y1 )
; ;
9 / 27
2D counting on monotonic functions
Consider the specification:
:
const m ; n ; w N;
:
var z Z;
: = # ( ) 2 [0 m ) [0 n ) j h (i j ) w gg
fP Z f i ; j :: :: ; <
T ;
: =
fQ Z z g
In the previous grid, with w = 20 we want to find z = 59 (in bold):
7 13 14 25 25 27 29 29 32 33
6 11 12 23 24 25 27 29 32 32
6 9 12 22 22 23 27 29 30 30
6 9 10 20 20 23 25 25 27 28
6 9 10 18 20 21 21 23 25 25
6 7 10 16 16 19 21 22 23 23
5 5 8 14 15 17 19 21 21 23
5 5 6 12 12 15 16 17 18 19
5 5 6 10 12 14 15 16 17 19
3 5 6 8 9 9 9 10 11 13
9 / 27
2D counting on monotonic functions
The value of Z depends on the contour line induced by w .
The contour line separates the grid points with altitude < w from
those with altitude w . It may contain values > w .
Example:
7 13 14 25 25 27 29 29 32 33
6 11 12 23 24 25 27 29 32 32
6 9 12 22 22 23 27 29 30 30
6 9 10 20 20 23 25 25 27 28
6 9 10 18 20 21 21 23 25 25
6 7 10 16 16 19 21 22 23 23
5 5 8 14 15 17 19 21 21 23
5 5 6 12 12 15 16 17 18 19
5 5 6 10 12 14 15 16 17 19
3 5 6 8 9 9 9 10 11 13
(0,0)
Notice: z = 59 =
10 / 27
2D counting on monotonic functions
The value of Z depends on the contour line induced by w .
The contour line separates the grid points with altitude < w from
those with altitude w . It may contain values > w .
Example:
7 13 14 25 25 27 29 29 32 33
6 11 12 23 24 25 27 29 32 32
6 9 12 22 22 23 27 29 30 30
6 9 10 20 20 23 25 25 27 28
6 9 10 18 20 21 21 23 25 25
6 7 10 16 16 19 21 22 23 23
5 5 8 14 15 17 19 21 21 23
5 5 6 12 12 15 16 17 18 19
5 5 6 10 12 14 15 16 17 19
3 5 6 8 9 9 9 10 11 13
(0,0)
Notice: z = 59 = 10 + 10 + 10 + 6 + 5 + 5 + 4 + 3 + 3 + 3 :
10 / 27
2D counting on monotonic functions
J : Z = z + F (x y )
;
where
I z is the number of already counted grid points
( )
I F x ; y denotes the points still to be counted, enclosed by an
area called the shrinking rectangle
11 / 27
Maintaining J : Z = z + F (x ; y )
contour
Intuitively: (0,n−1) line
00000000000000
11111111111111
00000000000000
11111111111111
F(x,y)
00000000000000
11111111111111
j
Less than w 00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
(0,0) x i (m−1,0)
12 / 27
Maintaining J : Z = z + F (x ; y )
contour
Intuitively: (0,n−1) line
12 / 27
Maintaining J : Z = z + F (x ; y )
contour
Intuitively: (0,n−1) line
12 / 27
Maintaining J : Z = z + F (x ; y )
contour
Intuitively: (0,n−1) line
We define:
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
12 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
14 25 25 27 29 29 32 33
Intuitively:
12 23 24 25 27 29 32 32
I At the beginning: 12 22 22 23 27 29 30 30
= ( )
Z F 0; n . 10 20 20 23 25 25 27 28
10 18 20 21 21 23 25 25
10 16 16 19 21 22 23 23
8 14 15 17 19 21 21 23
6 12 12 15 16 17 18 19
6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
14 25 25 27 29 29 32 33
Intuitively:
12 23 24 25 27 29 32 32
12 22 22 23 27 29 30 30
10 20 20 23 25 25 27 28
I Follow the contour line 10 18 20 21 21 23 25 25
to reduce the rectangle 10 16 16 19 21 22 23 23
8 14 15 17 19 21 21 23
6 12 12 15 16 17 18 19
6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
Intuitively: 14 25 25 27 29 29 32 33
12 23 24 25 27 29 32 32
12 22 22 23 27 29 30 30
10 20 20 23 25 25 27 28
I Follow the contour line 10 18 20 21 21 23 25 25
to reduce the rectangle 10 16 16 19 21 22 23 23
- increase x 8 14 15 17 19 21 21 23
6 12 12 15 16 17 18 19
6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
Intuitively: 14 25 25 27 29 29 32 33
12 23 24 25 27 29 32 32
12 22 22 23 27 29 30 30
10 20 20 23 25 25 27 28
I Follow the contour line 10 18 20 21 21 23 25 25
to reduce the rectangle 10 16 16 19 21 22 23 23
- increase x 8 14 15 17 19 21 21 23
6 12 12 15 16 17 18 19
6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
Intuitively: 14 25 25 27 29 29 32 33
12 23 24 25 27 29 32 32
12 22 22 23 27 29 30 30
10 20 20 23 25 25 27 28
I Follow the contour line 10 18 20 21 21 23 25 25
to reduce the rectangle 10 16 16 19 21 22 23 23
- decrease y 8 14 15 17 19 21 21 23
6 12 12 15 16 17 18 19
6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
Intuitively: 14 25 25 27 29 29 32 33
12 23 24 25 27 29 32 32
12 22 22 23 27 29 30 30
10 20 20 23 25 25 27 28
I Follow the contour line 10 18 20 21 21 23 25 25
to reduce the rectangle 10 16 16 19 21 22 23 23
- decrease y 8 14 15 17 19 21 21 23
6 12 12 15 16 17 18 19
6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
14 25 25 27 29 29 32 33
Intuitively:
12 23 24 25 27 29 32 32
12 22 22 23 27 29 30 30
10 20 20 23 25 25 27 28
I Follow the contour line 10 18 20 21 21 23 25 25
to reduce the rectangle 10 16 16 19 21 22 23 23
8 14 15 17 19 21 21 23
6 12 12 15 16 17 18 19
6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
14 25 25 27 29 29 32 33
Intuitively:
12 23 24 25 27 29 32 32
12 22 22 23 27 29 30 30
10 20 20 23 25 25 27 28
I Follow the contour line 10 18 20 21 21 23 25 25
to reduce the rectangle 10 16 16 19 21 22 23 23
8 14 15 17 19 21 21 23
6 12 12 15 16 17 18 19
6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
14 25 25 27 29 29 32 33
Intuitively:
12 23 24 25 27 29 32 32
12 22 22 23 27 29 30 30
10 20 20 23 25 25 27 28
I Follow the contour line 10 18 20 21 21 23 25 25
to reduce the rectangle 10 16 16 19 21 22 23 23
8 14 15 17 19 21 21 23
6 12 12 15 16 17 18 19
6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Maintaining Z = z + F (x ; y ), Intuitively
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
14 25 25 27 29 29 32 33
Intuitively:
12 23 24 25 27 29 32 32
12 22 22 23 27 29 30 30
10 20 20 23 25 25 27 28
10 18 20 21 21 23 25 25
10 16 16 19 21 22 23 23
8 14 15 17 19 21 21 23
I At the end:
( )= = z.
6 12 12 15 16 17 18 19
F m; 0 0 and Z 6 10 12 14 15 16 17 19
6 8 9 9 9 10 11 13
13 / 27
Recurrence for F (x ; y )
contour
(0,n−1) line
At least w
z 11111111111111
00000000000000
00000000000000
11111111111111
00000000000000
11111111111111
y
00000000000000
11111111111111
00000000000000
11111111111111
F(x,y) j
Less than w
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
(0,0) x i (m−1,0)
( )
We characterize the rectangle F x ; y with a recurrence relation.
Side conditions relevant for counting:
I x < m (and m x )
I y > 0 (and y 0)
( ) ( )
I h x ; y 1 < w (and h x ; y 1 w )
Because #; = 0, we have the base case:
m x _ y 0 ) F (x y ) = 0 ;
14 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
( )
F x;y
= { definition F }
#( ) : i
f i; j j i; j x < m ^ 0j < y ^ h (i j )
; < wg
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
#f(i j ) j i j : x + 1 i m ^ 0 j y ^ h (i j ) w g +
; ; < < ; <
#f(x j ) j j : 0 j y ^ h (x j ) w g
; < ; <
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
#f(i j ) j i j : x + 1 i m ^ 0 j y ^ h (i j ) w g +
; ; < < ; <
#f(x j ) j j : 0 j y ^ h (x j ) w g
; < ; <
= { definition F }
F (x + 1 y ) + #f(x j ) j j : 0 j y ^ h (x j ) w g
; ; < ; <
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
#f(i j ) j i j : x + 1 i m ^ 0 j y ^ h (i j ) w g +
; ; < < ; <
#f(x j ) j j : 0 j y ^ h (x j ) w g
; < ; <
= { definition F }
F (x + 1 y ) + #f(x j ) j j : 0 j y ^ h (x j ) w g
; ; < ; <
= { assume y 0; h (x j ) is ascending in j so h (x y 1) is
> ; ;
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
#f(i j ) j i j : x + 1 i m ^ 0 j y ^ h (i j ) w g +
; ; < < ; <
#f(x j ) j j : 0 j y ^ h (x j ) w g
; < ; <
= { definition F }
F (x + 1 y ) + #f(x j ) j j : 0 j y ^ h (x j ) w g
; ; < ; <
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
#f(i j ) j i j : x + 1 i m ^ 0 j y ^ h (i j ) w g +
; ; < < ; <
#f(x j ) j j : 0 j y ^ h (x j ) w g
; < ; <
= { definition F }
F (x + 1 y ) + #f(x j ) j j : 0 j y ^ h (x j ) w g
; ; < ; <
assume h (x y 1) w , ; <
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
#f(i j ) j i j : x + 1 i m ^ 0 j y ^ h (i j ) w g +
; ; < < ; <
#f(x j ) j j : 0 j y ^ h (x j ) w g
; < ; <
= { definition F }
F (x + 1 y ) + #f(x j ) j j : 0 j y ^ h (x j ) w g
; ; < ; <
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
#f(i j ) j i j : x + 1 i m ^ 0 j y ^ h (i j ) w g +
; ; < < ; <
#f(x j ) j j : 0 j y ^ h (x j ) w g
; < ; <
= { definition F }
F (x + 1 y ) + #f(x j ) j j : 0 j y ^ h (x j ) w g
; ; < ; <
F (x + 1 y ) + #f(x j ) j j : 0 j y g
; ; <
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
#f(i j ) j i j : x + 1 i m ^ 0 j y ^ h (i j ) w g +
; ; < < ; <
#f(x j ) j j : 0 j y ^ h (x j ) w g
; < ; <
= { definition F }
F (x + 1 y ) + #f(x j ) j j : 0 j y ^ h (x j ) w g
; ; < ; <
F (x + 1 y ) + #f(x j ) j j : 0 j y g
; ; <
F (x + 1 y ) + y
;
15 / 27
Recurrence for F (x ; y )
One way to reduce the rectangle is to increment x .
We exploit that h is ascending in y:
F (x y )
;
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume x m; so x i m (x + 1 i m _ i = x ) }
< < <
#f(i j ) j i j : x + 1 i m ^ 0 j y ^ h (i j ) w g +
; ; < < ; <
#f(x j ) j j : 0 j y ^ h (x j ) w g
; < ; <
= { definition F }
F (x + 1 y ) + #f(x j ) j j : 0 j y ^ h (x j ) w g
; ; < ; <
F (x + 1 y ) + #f(x j ) j j : 0 j y g
; ; <
F (x + 1 y ) + y
;
Conclusion:
x <m ^ y >0 ^ h (x ; y 1 ) < w ) F (x y ) = F (x + 1 y ) + y
; ;
15 / 27
Recurrence for F (x ; y )
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i
; ; < m ^ 0j < y ^ h (i j )
; < wg
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y
> < < )
1 }
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y 1) }
> < <
#f(i j ) j i j : x i m ^ 0 j y 1 ^ h (i j ) w g +
; ; < < ; <
#f(i y 1) j i : x i m ^ h (i y 1) w g
; < ; <
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y 1) }
> < <
#f(i j ) j i j : x i m ^ 0 j y 1 ^ h (i j ) w g +
; ; < < ; <
#f(i y 1) j i : x i m ^ h (i y 1) w g
; < ; <
= { definition F }
F (x y 1) + #f(i y 1) j i : x i m ^ h (i y 1) w g
; ; < ; <
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y 1) }
> < <
#f(i j ) j i j : x i m ^ 0 j y 1 ^ h (i j ) w g +
; ; < < ; <
#f(i y 1) j i : x i m ^ h (i y 1) w g
; < ; <
= { definition F }
F (x y 1) + #f(i y 1) j i : x i m ^ h (i y 1) w g
; ; < ; <
= { h (i y 1) is ascending in i so h (x y 1) is
; ;
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y 1) }
> < <
#f(i j ) j i j : x i m ^ 0 j y 1 ^ h (i j ) w g +
; ; < < ; <
#f(i y 1) j i : x i m ^ h (i y 1) w g
; < ; <
= { definition F }
F (x y 1) + #f(i y 1) j i : x i m ^ h (i y 1) w g
; ; < ; <
= { h (i y 1) is ascending in i so h (x y 1) is minimal;
; ;
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y 1) }
> < <
#f(i j ) j i j : x i m ^ 0 j y 1 ^ h (i j ) w g +
; ; < < ; <
#f(i y 1) j i : x i m ^ h (i y 1) w g
; < ; <
= { definition F }
F (x y 1) + #f(i y 1) j i : x i m ^ h (i y 1) w g
; ; < ; <
= { h (i y 1) is ascending in i so h (x y 1) is minimal;
; ;
assume h (x y 1) w :
;
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y 1) }
> < <
#f(i j ) j i j : x i m ^ 0 j y 1 ^ h (i j ) w g +
; ; < < ; <
#f(i y 1) j i : x i m ^ h (i y 1) w g
; < ; <
= { definition F }
F (x y 1) + #f(i y 1) j i : x i m ^ h (i y 1) w g
; ; < ; <
= { h (i y 1) is ascending in i so h (x y 1) is minimal;
; ;
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y 1) }
> < <
#f(i j ) j i j : x i m ^ 0 j y 1 ^ h (i j ) w g +
; ; < < ; <
#f(i y 1) j i : x i m ^ h (i y 1) w g
; < ; <
= { definition F }
F (x y 1) + #f(i y 1) j i : x i m ^ h (i y 1) w g
; ; < ; <
= { h (i y 1) is ascending in i so h (x y 1) is minimal;
; ;
F (x y 1) + #f(i y 1) j i : x i m ^ falseg
; ; <
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y 1) }
> < <
#f(i j ) j i j : x i m ^ 0 j y 1 ^ h (i j ) w g +
; ; < < ; <
#f(i y 1) j i : x i m ^ h (i y 1) w g
; < ; <
= { definition F }
F (x y 1) + #f(i y 1) j i : x i m ^ h (i y 1) w g
; ; < ; <
= { h (i y 1) is ascending in i so h (x y 1) is minimal;
; ;
F (x y 1) + #f(i y 1) j i : x i m ^ falseg
; ; <
= { #; = 0}
F (x y 1)
;
16 / 27
Recurrence for F (x ; y )
= { definition F }
#f(i j ) j i j : x i m ^ 0 j y ^ h (i j ) w g
; ; < < ; <
= { assume y 0: then 0 j y (0 j y 1 _ j = y 1) }
> < <
#f(i j ) j i j : x i m ^ 0 j y 1 ^ h (i j ) w g +
; ; < < ; <
#f(i y 1) j i : x i m ^ h (i y 1) w g
; < ; <
= { definition F }
F (x y 1) + #f(i y 1) j i : x i m ^ h (i y 1) w g
; ; < ; <
= { h (i y 1) is ascending in i so h (x y 1) is minimal;
; ;
F (x y 1) + #f(i y 1) j i : x i m ^ falseg
; ; <
= { #; = 0}
F (x y 1)
;
Conclusion: y 0 ^ h (x y 1) w ) F (x y ) = F (x y 1)
> ; ; ;
16 / 27
Recurrence for F (x ; y )
We conclude that
(
F x;y ) = #f(i j ) j i j : x i
; ; < m ^0j < y ^ h (i j )
; < wg
m x _y 0 ) ( )=0
F x;y
x < m ^y > 0 ^ h (x y 1) w )
; < F (x y ) = y + F (x + 1 y )
; ;
y > 0 ^ h (x y 1) w )
; F (x y ) = F (x y 1)
; ;
17 / 27
2D counting: Guard & Invariant
We now rewrite the original specification to obtain:
const m ; n ; w : N;
var z : Z;
fP : Z = F (0; n )g
T;
fQ : Z = z g
18 / 27
2D counting: Guard & Invariant
We now rewrite the original specification to obtain:
const m ; n ; w : N;
var z : Z;
fP : Z = F (0; n )g
T;
fQ : Z = z g
0 We decide that we need a while-program: we will try to reduce te size of the
remaining rectangle by incrementing x or decrementing y iteratively.
18 / 27
2D counting: Guard & Invariant
We now rewrite the original specification to obtain:
const m ; n ; w : N;
var z : Z;
fP : Z = F (0; n )g
T;
fQ : Z = z g
0 We decide that we need a while-program: we will try to reduce te size of the
remaining rectangle by incrementing x or decrementing y iteratively.
1 We introduce the variables x ; y : Z and the invariant and guard
J :Z = z + F (x ; y )
B :x < m ^ y > 0
18 / 27
2D counting: Guard & Invariant
We now rewrite the original specification to obtain:
const m ; n ; w : N;
var z : Z;
fP : Z = F (0; n )g
T;
fQ : Z = z g
0 We decide that we need a while-program: we will try to reduce te size of the
remaining rectangle by incrementing x or decrementing y iteratively.
1 We introduce the variables x ; y : Z and the invariant and guard
J :Z = z + F (x ; y )
B :x < m ^ y > 0
J ^ :B
{ definition J and B }
= z + F (x ; y ) ^ :(x < m ^ y > 0)
Z
{ Logic; De Morgan }
Z = z + F ( x ; y ) ^ ( m x _ y 0)
) { base case recurrence: F (x ; y ) = 0 }
Q :Z =z
18 / 27
2D counting: Initialization & Variant
( )
2 Initialization: We start with x ; y in the North-West corner:
19 / 27
2D counting: Initialization & Variant
( )
2 Initialization: We start with x ; y in the North-West corner:
contour
(0,n−1) line
fP : = (
Z F 0; n g ) At least w
(* calculus *)
11111111111111
00000000000000
= +
fZ 0 F 0; n g( )
z
00000000000000
11111111111111
00000000000000
11111111111111
y
z := ; :=
0 x ;
0 y n:= ; 00000000000000
11111111111111
00000000000000
11111111111111
F(x,y)
00000000000000
11111111111111
j
: = +
fJ Z z F x ; y ( )g Less than w 00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
(0,0) x i (m−1,0)
19 / 27
2D counting: Initialization & Variant
( )
2 Initialization: We start with x ; y in the North-West corner:
contour
(0,n−1) line
fP : = (
Z F 0; n g ) At least w
(* calculus *)
11111111111111
00000000000000
= +
fZ 0 F 0; n g( )
z
00000000000000
11111111111111
00000000000000
11111111111111
y
z := ; :=
0 x ;
0 y n:= ; 00000000000000
11111111111111
00000000000000
11111111111111
F(x,y)
00000000000000
11111111111111
j
: = +
fJ Z z F x ; y ( )g Less than w 00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
(0,0) x i (m−1,0)
19 / 27
2D counting: Initialization & Variant
( )
2 Initialization: We start with x ; y in the North-West corner:
contour
(0,n−1) line
fP : = (
Z F 0; n g ) At least w
(* calculus *)
11111111111111
00000000000000
= +
fZ 0 F 0; n g( )
z
00000000000000
11111111111111
00000000000000
11111111111111
y
z := ; :=
0 x ;
0 y n:= ; 00000000000000
11111111111111
00000000000000
11111111111111
F(x,y)
00000000000000
11111111111111
j
: = +
fJ Z z F x ; y ( )g Less than w 00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
00000000000000
11111111111111
(0,0) x i (m−1,0)
19 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
else
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y +m x = Vg
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y +m x = Vg
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y +m x = Vg
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
z := z + y ;
fZ = z + F (x + 1; y ) ^ y + m x = V g
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y +m x = Vg
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
z := z + y ;
fZ = z + F (x + 1; y ) ^ y + m x = V g
(* calculus; prepare x := x + 1 *)
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y +m x = Vg
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
z := z + y ;
fZ = z + F (x + 1; y ) ^ y + m x = V g
(* calculus; prepare x := x + 1 *)
fZ = z + F (x + 1; y ) ^ y + m (x + 1) < V g
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y +m x = Vg
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
z := z + y ;
fZ = z + F (x + 1; y ) ^ y + m x = V g
(* calculus; prepare x := x + 1 *)
fZ = z + F (x + 1; y ) ^ y + m (x + 1) < V g
x := x + 1;
fZ = z + F (x ; y ) ^ y + m x < V g
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
z := z + y ;
fZ = z + F (x + 1; y ) ^ y + m x = V g
(* calculus; prepare x := x + 1 *)
fZ = z + F (x + 1; y ) ^ y + m (x + 1) < V g
x := x + 1;
fZ = z + F (x ; y ) ^ y + m x < V g
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case y > 0 ^ h (x ; y 1) w *)
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
z := z + y ;
fZ = z + F (x + 1; y ) ^ y + m x = V g
(* calculus; prepare x := x + 1 *)
fZ = z + F (x + 1; y ) ^ y + m (x + 1) < V g
x := x + 1;
fZ = z + F (x ; y ) ^ y + m x < V g
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case y > 0 ^ h (x ; y 1) w *)
fZ = z + F (x ; y 1) ^ y + m x = V g
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
z := z + y ;
fZ = z + F (x + 1; y ) ^ y + m x = V g
(* calculus; prepare x := x + 1 *)
fZ = z + F (x + 1; y ) ^ y + m (x + 1) < V g
x := x + 1;
fZ = z + F (x ; y ) ^ y + m x < V g
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case y > 0 ^ h (x ; y 1) w *)
fZ = z + F (x ; y 1) ^ y + m x = V g
(* calculus; prepare y := y 1 *)
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
z := z + y ;
fZ = z + F (x + 1; y ) ^ y + m x = V g
(* calculus; prepare x := x + 1 *)
fZ = z + F (x + 1; y ) ^ y + m (x + 1) < V g
x := x + 1;
fZ = z + F (x ; y ) ^ y + m x < V g
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case y > 0 ^ h (x ; y 1) w *)
fZ = z + F (x ; y 1) ^ y + m x = V g
(* calculus; prepare y := y 1 *)
fZ = z + F (x ; y 1) ^ y 1 + m x < V g
end
fJ ^ vf < Vg
20 / 27
2D counting: Body of the Loop
fZ = z + F (x y ) ^ x m ^ y 0 ^ y + m x = V g
; < >
if h (x ; y 1) < w then
fh (x ; y 1) < w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case x < m ^ y > 0 ^ h (x ; y 1) < w *)
fZ = z + y + F (x + 1; y ) ^ y + m x = V g
z := z + y ;
fZ = z + F (x + 1; y ) ^ y + m x = V g
(* calculus; prepare x := x + 1 *)
fZ = z + F (x + 1; y ) ^ y + m (x + 1) < V g
x := x + 1;
fZ = z + F (x ; y ) ^ y + m x < V g
else
fh (x ; y 1) w ^ Z = z + F (x ; y ) ^ x < m ^ y > 0 ^ y + m x = V g
(* logic; recurrence for F (x ; y ): case y > 0 ^ h (x ; y 1) w *)
fZ = z + F (x ; y 1) ^ y + m x = V g
(* calculus; prepare y := y 1 *)
fZ = z + F (x ; y 1) ^ y 1 + m x < V g
y := y 1;
fZ = z + F (x ; y ) ^ y + m x < V g
end (* collect branches; definitions J and vf *)
fJ ^ vf < V g 20 / 27
2D counting: Conclusion
:
const m ; n ; w N;
:
var x ; y ; z Z;
: =# ( ) [
fP Z f i ; j 2 0::m ) [0 n ) j h (i j )
:: ; < wg g
z:= ; 0
x:= ; 0
y:= ; n
: = + ( )
fJ Z z F x ; y g
: +
(* vf y m x *)
while x < m ^ y > 0 do
( )
if h x ; y 1 < w then
z := + ;y z
x := + ;x 1
else
y := ;
y 1
end ;
end;
: =
fQ z Z g
21 / 27
2D counting: Conclusion
const m ; n ; w N; :
:
var x ; y ; z Z;
: = # ( ) [ ) [0 n ) j h (i j ) w g g
fP Z f i ; j 2 0::m :: ; <
z := ;
0
x := ;
0
y := ;
n
: = + ( )
fJ Z z F x ; y g
: +
(* vf y m x *)
while x < m ^ y > 0 do
( )
if h x ; y 1 < w then
z := + ;
y z
x := + ;
x 1
else
y := y 1 ;
end ;
end ;
: =
fQ z Z g
Note: Initially, vf = m + n, so the time complexity is O (m + n ), more
efficient than the brute-force O (m n ) algorithm. 21 / 27
Outline
22 / 27
The Shrinking Area Method
: = + (
I For counting, we use the invariant J Z z F x ; y . )
(A variation is needed for, e.g., minimization problems).
( )
I Given a function h x ; y , the method depends on the
monotonicty properties of x and y.
I In turn, such properties define the contour line and its slope.
( )
I The area F x ; y (and the way it is iteratively reduced) depends
on this slope (and on the spec of the command).
( )
I A recurrence relation for F x ; y must be determined.
The side conditions of the recurrence capture the area we want
to cover; they usually guide the conditionals in the command.
( )
I The spec for counting may include a constraint on points i ; j .
Such a constraint determines a section of the area; it typically
appears as the guard of the loop.
24 / 27
Different Functions & Contour Line (1/2)
:
Suppose a function h N N ! Z that is descending on x and
ascending on y:
x0 x1 ) h (x0 y ) h (x1 y )
; ;
y0 y1 ) h (x y0 ) h (x y1 )
; ;
25 / 27
Different Functions & Contour Line (2/2)
:
Now suppose a function g N N ! Z that is increasing in x and
descending in y:
x0 <) g ( x0 y ) g ( x1 y )
x1 ; < ;
y0 y1 ) g ( x y0 ) g ( x y1 )
; ;
26 / 27
The End
27 / 27