CSE 331�Software Design & Implementation
Spring 2026
Section 3 – Floyd Logic
Administrivia
2
Forward Reasoning – Review
R
P
{{P}}
S
{{R}}
{{Q}}
Forward Reasoning Error Example
{{ x > 1 }}
x = x + 1;
{{ x = x0 + 1 and x0 > 1 }}
y = 3 * x;
{{ x = x0 + 1 and y = 3 * x }}
z = y + 1;
{{ x = x0 + 1 and z = (3 * x) + 1 }}
What’s wrong with these assertions?
Drops this assertion
Substitutes/simplifies assertions too early by dropping y variable relationship to x
Corrected Forward Reasoning Example
{{ x > 1 }}
x = x + 1;
{{ x - 1 > 1 }}
y = 3 * x;
{{ x - 1 > 1 and y = 3 * x }}
z = y + 1
{{ x - 1 > 1 and y = 3 * x and z = y + 1 }}
Unless specified, we allow both inverted operations and subscripts!
does not simplify assertions early or drop variable relationships
Backward Reasoning – Review
R
Q
{{P}}
{{R}}
S
{{Q}}
Forward & Backward General Rules
Forward Reasoning:
Backward Reasoning:
General:
Task 1 - Found Guilty of Reason
{{y > 5 and z > 2}}
x = 4 * y - 3
{{-}}
y = y - 5
{{-}}
z = z * y
{{P: }}
{{Q: x < 2z + 20}}
Task 1 - Found Guilty of Reason
{{y > 5 and z > 2}}
x = 4 * y - 3
{{y > 5 and z > 2 and x = 4y - 3}}
y = y - 5
{{-}}
z = z * y
{{P: }}
{{Q: x < 2z + 20}}
Task 1 - Found Guilty of Reason
{{y > 5 and z > 2}}
x = 4 * y - 3
{{y > 5 and z > 2 and x = 4y - 3}}
y = y - 5
{{y + 5 > 5 and z > 2 and x = 4(y + 5) - 3}}
z = z * y
{{P: }}
{{Q: x < 2z + 20}}
Task 1 - Found Guilty of Reason
{{y > 5 and z > 2}}
x = 4 * y - 3
{{y > 5 and z > 2 and x = 4y - 3}}
y = y - 5
{{y + 5 > 5 and z > 2 and x = 4(y + 5) - 3}}
z = z * y
{{P: y + 5 > 5 and z / y > 2 and x = 4(y + 5) - 3}}
{{Q: x < 2z + 20}}
Task 1 - Found Guilty of Reason
b) Show that the code is correct by explaining how P implies Q
{{P: y + 5 > 5 and z / y > 2 and x = 4(y + 5) - 3}}
{{Q: x < 2z + 20}}
Task 1 - Found Guilty of Reason
b) Show that the code is correct by explaining how P implies Q
{{P: y + 5 > 5 and z / y > 2 and x = 4(y + 5) - 3}}
{{Q: x < 2z + 20}}
x = 4y + 17 (since x = 4(y + 5) - 3)
< 2z + 17 (since z > 2y because y > 0)
< 2z + 20
Alternate solution: We know that x = 4(y + 5) - 3 = 4y + 20 - 3 = 4y + 17. Next, we can rewrite z / y > 2 into z > 2y since we know that y > 0 (and therefore multiplying both sides by y doesn't flip the sign). We can then substitute into our original equation that x < 2z + 17. Finally, we know that 17 < 20 so x < 2z + 17. Therefore, Q holds.
Task 1 - Found Guilty of Reason
c) Use forward reasoning to fill in the missing assertions in the following code:
/*
* Computes the square of (x + 1)
* @param x The number to increment and square
* @return (x + 1)^2
*/
public static int nextSquare(int x) {
int y = x * x;
{{ - }}
y = y + (2 * x);
{{ - }}
y = y + 1;
{{P:}}
return y;
}
Task 1 - Found Guilty of Reason
c) Use forward reasoning to fill in the missing assertions in the following code:
/*
* Computes the square of (x + 1)
* @param x The number to increment and square
* @return (x + 1)^2
*/
public static int nextSquare(int x) {
int y = x * x;
{{y = x^2}}
y = y + (2 * x);
{{ - }}
y = y + 1;
{{P:}}
return y;
}
Task 1 - Found Guilty of Reason
c) Use forward reasoning to fill in the missing assertions in the following code:
/*
* Computes the square of (x + 1)
* @param x The number to increment and square
* @return (x + 1)^2
*/
public static int nextSquare(int x) {
int y = x * x;
{{y = x^2}}
y = y + (2 * x);
{{y - 2x = x^2}}
y = y + 1;
{{P:}}
return y;
}
Task 1 - Found Guilty of Reason
c) Use forward reasoning to fill in the missing assertions in the following code:
/*
* Computes the square of (x + 1)
* @param x The number to increment and square
* @return (x + 1)^2
*/
public static int nextSquare(int x) {
int y = x * x;
{{y = x^2}}
y = y + (2 * x);
{{y - 2x = x^2}}
y = y + 1;
{{P: y - 2x - 1 = x^2 → y = x^2 + 2x + 1}}
return y;
}
Task 1 - Found Guilty of Reason
d) Show that the code is correct by explaining how P implies the postcondition:
{{P: y - 2x - 1 = x2}} ←→ {{P: y = x2 + 2x + 1}}
{{Q: y = (x + 1)2}}
Task 1 - Found Guilty of Reason
d) Show that the code is correct by explaining how P implies the postcondition:
{{P: y - 2x - 1 = x2}} ←→ {{P: y = x2 + 2x + 1}}
{{Q: y = (x + 1)2}}
y = x2 + 2x + 1 since y = x2 + 2x + 1
= (x + 1)2
Alternate solution: We know that y = x2 + 2x +1 which we can rewrite using algebra that y = (x + 1)2. Therefore, Q holds.
Task 2 - Does a Duck Say “Back”?
{{P: x < w + 1 and w > 0}}
{{Q:}}
y = 4 * w
{{ - }}
x = x * 2
{{x - 8 < y}}
z = x - 8
{{z < y}}
Task 2 - Does a Duck Say “Back”?
{{P: x < w + 1 and w > 0}}
{{Q:}}
y = 4 * w
{{2x - 8 < y}}
x = x * 2
{{x - 8 < y}}
z = x - 8
{{z < y}}
Task 2 - Does a Duck Say “Back”?
{{P: x < w + 1 and w > 0}}
{{Q: 2x - 8 < 4w → x < 2w + 4}}
y = 4 * w
{{2x - 8 < y}}
x = x * 2
{{x - 8 < y}}
z = x - 8
{{z < y}}
Task 2 - Does a Duck Say “Back”?
b) Show P implies Q
{{P: x < w + 1 and w > 0}}
{{Q: x < 2w + 4}}
We can see Q holds:
x < w + 1
< 2w + 1 (w > 0)
< 2w + 4
Alternate solution: Alternate solution: We know that x < w + 1. Since w > 0, we know that w < 2w, and w < 2w + 3. Thus, x < w + 1 < 2w + 4.
Task 2 - Does a Duck Say “Back”?
c) Use backward reasoning to fill in the missing assertions in the following code:
// Performs a simple calculation on c
// @param c The input integer
// @requires c >= 0
// @return an integer >= c
public static int calculation(int c) {
{{P: c >= 0}}
{{Q:}}
int b = 2 * c
{{ - }}
c = c - 1
{{ - }}
int a = b + 1
{{a >= c}}
return a;
}
Task 2 - Does a Duck Say “Back”?
c) Use backward reasoning to fill in the missing assertions in the following code:
// Performs a simple calculation on c
// @param c The input integer
// @requires c >= 0
// @return an integer >= c
public static int calculation(int c) {
{{P: c >= 0}}
{{Q:}}
int b = 2 * c
{{ - }}
c = c - 1
{{b + 1 >= c}}
int a = b + 1
{{a >= c}}
return a;
}
Task 2 - Does a Duck Say “Back”?
c) Use backward reasoning to fill in the missing assertions in the following code:
// Performs a simple calculation on c
// @param c The input integer
// @requires c >= 0
// @return an integer >= c
public static int calculation(int c) {
{{P: c >= 0}}
{{Q:}}
int b = 2 * c
{{b + 1 >= c - 1}}
c = c - 1
{{b + 1 >= c}}
int a = b + 1
{{a >= c}}
return a;
}
Task 2 - Does a Duck Say “Back”?
c) Use backward reasoning to fill in the missing assertions in the following code:
// Performs a simple calculation on c
// @param c The input integer
// @requires c >= 0
// @return an integer >= c
public static int calculation(int c) {
{{P: c >= 0}}
{{Q: 2c + 1 >= c - 1 → c >= -2}}
int b = 2 * c
{{b + 1 >= c - 1}}
c = c - 1
{{b + 1 >= c}}
int a = b + 1
{{a >= c}}
return a;
}
Task 2 - Does a Duck Say “Back”?
d) Show how P implies Q
{{P: c >= 0}}
{{Q: 2c + 1 >= c - 1 → c >= -2}}
We can see that Q holds since c >= 0 >= -2.
Conditionals – Review
public static int g(int n) {
{{ }}
int m = 0;
if (n >= 0) {
m = 2 * n + 1;
} else {
m = 0;
}
{{m > n}}
return m;
}
{{ }}
int m = 0;
if (n >= 0) {
m = 2 * n + 1;
} else {
m = 0;
}
{{m > n}}
return m;
}
Task 3 - Nothing to be If-ed At
Use forward reasoning to fill in the assertion
// Calculates a safe substring length starting from a given index
// @param start The starting index of the substring
// @param desired The desired substring length
// @param len The total length of the original string
// @requires 0 <= start < len and desired >= 0
// @return A window size such that start + window <= len
public static int calcWindow(int start, int desired, int len) {
{{ - }}
int window;
if (start + desired <= len) {
{{ - }}
window = desired;
{{P1:}}
} else {
{{ - }}
window = len - start;
{{P2:}}
}
{{ - }}
return window;
}
Task 3 - Nothing to be If-ed At
public static int calcWindow(int start, int desired, int len) {
{{0 <= start < len and desired >= 0}}
int window;
if (start + desired <= len) {
{{ - }}
window = desired;
{{P1:}}
} else {
{{ - }}
window = len - start;
{{P2:}}
}
{{ - }}
return window;
}
Task 3 - Nothing to be If-ed At
public static int calcWindow(int start, int desired, int len) {
{{0 <= start < len and desired >= 0}}
int window;
if (start + desired <= len) {
{{0 <= start < len and desired >= 0 and start + desired <= len}}
window = desired;
{{P1:}}
} else {
{{ - }}
window = len - start;
{{P2:}}
}
{{ - }}
return window;
}
Task 3 - Nothing to be If-ed At
public static int calcWindow(int start, int desired, int len) {
{{0 <= start < len and desired >= 0}}
int window;
if (start + desired <= len) {
{{0 <= start < len and desired >= 0 and start + desired <= len}}
window = desired;
{{P1: 0 <= start < len and desired >= 0 and start + desired <= len and window = desired}}
} else {
{{ - }}
window = len - start;
{{P2:}}
}
{{ - }}
return window;
}
Task 3 - Nothing to be If-ed At
public static int calcWindow(int start, int desired, int len) {
{{0 <= start < len and desired >= 0}}
int window;
if (start + desired <= len) {
{{0 <= start < len and desired >= 0 and start + desired <= len}}
window = desired;
{{P1: 0 <= start < len and desired >= 0 and start + desired <= len and window = desired}}
} else {
{{0 <= start < len and desired >= 0 and start + desired > len}}
window = len - start;
{{P2:}}
}
{{ - }}
return window;
}
Task 3 - Nothing to be If-ed At
public static int calcWindow(int start, int desired, int len) {
{{0 <= start < len and desired >= 0}}
int window;
if (start + desired <= len) {
{{0 <= start < len and desired >= 0 and start + desired <= len}}
window = desired;
{{P1: 0 <= start < len and desired >= 0 and start + desired <= len and window = desired}}
} else {
{{0 <= start < len and desired >= 0 and start + desired > len}}
window = len - start;
{{P2: 0 <= start < len and desired >= 0 and start + desired > len and window = len - start}}
}
{{ - }}
return window;
}
Task 3 - Nothing to be If-ed At
public static int calcWindow(int start, int desired, int len) {
{{0 <= start < len and desired >= 0}}
int window;
if (start + desired <= len) {
{{0 <= start < len and desired >= 0 and start + desired <= len}}
window = desired;
{{P1: 0 <= start < len and desired >= 0 and start + desired <= len and window = desired}}
} else {
{{0 <= start < len and desired >= 0 and start + desired > len}}
window = len - start;
{{P2: 0 <= start < len and desired >= 0 and start + desired > len and window = len - start}}
}
{{P1 or P2}}
return window;
}
Task 3 - Nothing to be If-ed At
The postcondition is “start + window <= len” and we know that “P1 or P2" is true. We will show that the postcondition holds in general:
Suppose P1 is true. We can see:
start + window = start + desired since window = desired
<= len since start + window <= len
Suppose P2 is true. We can see:
start + window = start + (len - start) since window = len - start
= len
<= len
Since these cases are exhaustive and we have shown that in either case the postcondition holds, we have proven that the postcondition holds in general.
Loop Invariant – Review
true!
{{Inv: I}}
while (cond) {
S
}
true!
true!
true!
Question ….
Where is it allowed for a loop invariant not to hold?
Question ….
Where is it allowed for a loop invariant not to hold?
Task 4 - Everybody Loops
In this problem, we will prove the correctness of a method containing a loop that finds the quotient of x divided by 10, i.e., the largest value y such that 10y <= x. To say that y is the largest such value means that any larger value would not satisfy the inequality, i.e., that 10(y + 1) !<= x…
Task 4 - Everybody Loops
// Computes the integer quotient of x divided by 10
// @param x The numerator
// @requires x >= 0
// @return The largest integer y such that 10 * y <= x_0
public static int divideByTen(int x) {
{{ x = x_0 and x_0 >= 0 }}
int y = 0;
{{ P1: _________________________ }}
{{ Inv: x_0 - 10y = x and x >= 0 }}
while (x >= 10) {
{{ _____________________________ }}
y = y + 1;
{{ _____________________________ }}
x = x - 10;
{{ P3: _________________________ }}
{{ Q2: _________________________ }}
}
{{ P2: _________________________ }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
return y;
}
Task 4 - Everybody Loops
{{ x = x_0 and x_0 >= 0 }}
int y = 0;
{{ P1: _________________________ }}
{{ Inv: x_0 - 10y = x and x >= 0 }}
Task 4 - Everybody Loops
{{ x = x_0 and x_0 >= 0 }}
int y = 0;
{{ P1: x = x_0 and x_0 >= 0 and y = 0 }}
{{ Inv: x_0 - 10y = x and x >= 0 }}
Task 4 - Everybody Loops
{{ x = x_0 and x_0 >= 0 }}
int y = 0;
{{ P1: x = x_0 and x_0 >= 0 and y = 0 }}
{{ Inv: x_0 - 10y = x and x >= 0 }}
The first part of the invariant holds
x_0 - 10y = x - 10y since x = x_0
= x since y = 0
Task 4 - Everybody Loops
{{ x = x_0 and x_0 >= 0 }}
int y = 0;
{{ P1: x = x_0 and x_0 >= 0 and y = 0 }}
{{ Inv: x_0 - 10y = x and x >= 0 }}
The first part of the invariant holds
x_0 - 10y = x - 10y since x = x_0
= x since y = 0
The second fact holds since x = x_0 >= 0
Task 4 - Everybody Loops
b) Fill in P2, then show that Q1 holds when we exit the loop.
{{ Inv: x_0 - 10y = x and x >= 0 }}
while (x >= 10) {
// Loop body
}
{{ P2: _________________________ }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
return y;
Task 4 - Everybody Loops
b) Fill in P2, then show that Q1 holds when we exit the loop.
{{ Inv: x_0 - 10y = x and x >= 0 }}
while (x >= 10) {
// Loop body
}
{{ P2: Inv (x_0 - 10y = x and x >= 0) and x < 10 }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
return y;
Task 4 - Everybody Loops
b) Fill in P2, then show that Q1 holds when we exit the loop.
{{ P2: Inv (x_0 - 10y = x and x >= 0) and x < 10 }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
Task 4 - Everybody Loops
b) Fill in P2, then show that Q1 holds when we exit the loop.
{{ P2: Inv (x_0 - 10y = x and x >= 0) and x < 10 }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
When we exit the loop, we know that P2: inv (x_0 - 10y = x, x ≥ 0), and x < 10. The first part of the postcondition holds since
10y = x_0 - x since x_0 - 10y = x
Task 4 - Everybody Loops
b) Fill in P2, then show that Q1 holds when we exit the loop.
{{ P2: Inv (x_0 - 10y = x and x >= 0) and x < 10 }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
When we exit the loop, we know that P2: inv (x0 - 10y = x, x ≥ 0), and x < 10. The first part of the postcondition holds since
10y = x_0 - x since x_0 - 10y = x
≤ x_0 since x ≥ 0
Task 4 - Everybody Loops
b) Fill in P2, then show that Q1 holds when we exit the loop.
{{ P2: Inv (x_0 - 10y = x and x >= 0) and x < 10 }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
When we exit the loop, we know that P2: inv (x0 - 10y = x, x ≥ 0), and x < 10. The first part of the postcondition holds since
10y = x_0 - x since x_0 - 10y = x
≤ x_0 since x ≥ 0
the second part of the postcondition holds since
x_0 = x + 10y since x_0 - 10y = x
Task 4 - Everybody Loops
b) Fill in P2, then show that Q1 holds when we exit the loop.
{{ P2: Inv (x_0 - 10y = x and x >= 0) and x < 10 }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
When we exit the loop, we know that P2: inv (x0 - 10y = x, x ≥ 0), and x < 10. The first part of the postcondition holds since
10y = x_0 - x since x_0 - 10y = x
≤ x_0 since x ≥ 0
the second part of the postcondition holds since
x_0 = x + 10y since x_0 - 10y = x
< 10 + 10y since x < 10
Task 4 - Everybody Loops
b) Fill in P2, then show that Q1 holds when we exit the loop.
{{ P2: Inv (x_0 - 10y = x and x >= 0) and x < 10 }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
When we exit the loop, we know that P2: inv (x0 - 10y = x, x ≥ 0), and x < 10. The first part of the postcondition holds since
10y = x_0 - x since x_0 - 10y = x
≤ x_0 since x ≥ 0
the second part of the postcondition holds since
x_0 = x + 10y since x_0 - 10y = x
< 10 + 10y since x < 10
= 10(y + 1)
Task 4 - Everybody Loops
b) Fill in P2, then show that Q1 holds when we exit the loop.
{{ P2: Inv (x_0 - 10y = x and x >= 0) and x < 10 }}
{{ Q1: 10y <= x_0 and x_0 < 10(y+1) and x = x_0 - 10y }}
and the third part is a restatement of the first fact from the invariant. Because the method returns y, and Q implies the required bounds for the quotient, the code correctly satisfies the @return specification.
Task 4 - Everybody Loops
c) Fill in Q2 (Hint: what do we know at the end of a loop?). Then, forward reason to P3. Show that P3 implies Q2, proving that the body of the loop is correct.
{{ Inv: x_0 - 10y = x and x >= 0 }}
while (x >= 10) {
{{ _____________________________ }}
y = y + 1;
{{ _____________________________ }}
x = x - 10;
{{ P3: _________________________ }}
{{ Q2: _________________________ }}
}
Task 4 - Everybody Loops
c) Fill in Q2 (Hint: what do we know at the end of a loop?). Then, forward reason to P3. Show that P3 implies Q2, proving that the body of the loop is correct.
{{ Inv: x_0 - 10y = x and x >= 0 }}
while (x >= 10) {
{{ _____________________________ }}
y = y + 1;
{{ _____________________________ }}
x = x - 10;
{{ P3: _________________________ }}
{{ Q2: Inv: x_0 - 10y = x and x >= 0 }}
}
Task 4 - Everybody Loops
c) Fill in Q2 (Hint: what do we know at the end of a loop?). Then, forward reason to P3. Show that P3 implies Q2, proving that the body of the loop is correct.
{{ Inv: x_0 - 10y = x and x >= 0 }}
while (x >= 10) {
{{ x_0 - 10y = x and x >= 0 and x >= 10 }}
y = y + 1;
{{ _____________________________ }}
x = x - 10;
{{ P3: _________________________ }}
{{ Q2: Inv: x_0 - 10y = x and x >= 0 }}
}
Task 4 - Everybody Loops
c) Fill in Q2 (Hint: what do we know at the end of a loop?). Then, forward reason to P3. Show that P3 implies Q2, proving that the body of the loop is correct.
{{ Inv: x_0 - 10y = x and x >= 0 }}
while (x >= 10) {
{{ x_0 - 10y = x and x >= 0 and x >= 10 }}
y = y + 1;
{{ x_0 - 10(y - 1) = x and x >= 0 and x >= 10 }}
x = x - 10;
{{ P3: _________________________ }}
{{ Q2: Inv: x_0 - 10y = x and x >= 0 }}
}
Task 4 - Everybody Loops
c) Fill in Q2 (Hint: what do we know at the end of a loop?). Then, forward reason to P3. Show that P3 implies Q2, proving that the body of the loop is correct.
{{ Inv: x_0 - 10y = x and x >= 0 }}
while (x >= 10) {
{{ x_0 - 10y = x and x >= 0 and x >= 10 }}
y = y + 1;
{{ x_0 - 10(y - 1) = x and x >= 0 and x >= 10 }}
x = x - 10;
{{ P3: x_0 - 10(y - 1) = x + 10 and x + 10 >= 0 and x + 10 >= 10 }}
{{ Q2: Inv: x_0 - 10y = x and x >= 0 }}
}
Task 4 - Everybody Loops
c) Fill in Q2 (Hint: what do we know at the end of a loop?). Then, forward reason to P3. Show that P3 implies Q2, proving that the body of the loop is correct.
{{ P3: x_0 - 10(y - 1) = x + 10 and x + 10 >= 0 and x + 10 >= 10 }}
{{ Q2: Inv: x_0 - 10y = x and x >= 0 }}
We must show P3 implies the invariant:
From P3, we know that x0 - 10(y - 1) = x + 10. Simplifying this:
x0 - 10y + 10 = x + 10
x0 - 10y = x
Also from P3, we know x + 10 >= 10. Subtracting 10 from both sides gives us x >= 0. Thus, the invariant holds.