CSE 331�Software Design & Implementation
Autumn 2026
Section 3 – Reasoning
Warm-Up (Hoare Triple Validity)
For each of the following Hoare Triples, decide whether it is valid or invalid. �If it is invalid, provide a counterexample.
A
{{ x > 0 }} x = x - 1; {{ x > 0 }} | B {{ x >= 10 }} if (x < 5) { y = -100; } else { y = x; } {{ y >= 10 }} | C {{ x = a and y = b }} x = x + y; y = x - y; x = x - y; {{ x = b and y = a }} |
D {{ x = a and y = b }} x = y; y = x; {{ x = b and y = a }} | E {{ n >= 0 }} i = 1; while (i <= n) { i = i + 1; } {{ i = n + 1 }} | F {{ x + 1 > 0 }} if (x < 0) { y = -x; } else { y = x; } {{ y > 0 }} |
Administrivia
3
Forward Reasoning – Review
R
P
{{P}}
S
{{R}}
{{Q}}
Forward Reasoning Basic Example
{{ w > 0 }}
x = 17;
{{ }}
y = 42;
{{ x - 1 > 1 and y = 3 * x }}
z = w + x + y;
{{ x - 1 > 1 and y = 3 * x and z = y + 1 }}
w > 0 and x = 17
w > 0 and x = 17 and y = 42
w > 0 and x = 17 and y = 42 and z = w + x + y
Append new facts to your collection as you move down the code
Notice that we did not combine or drop any facts
Forward Reasoning Tools
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;
{{ x0 > 1 and x = x0 + 1 }}
y = 3 * x;
{{ x0 > 1 and x = x0 + 1 and y = 3 * x }}
z = y + 1
{{ x0 > 1 and x = x0 + 1 and y = 3 * x and z = y + 1 }}
does not simplify assertions early or drop variable relationships
Invertible Operation Examples
{{ x = y }}
x = x + 1;
{{ x - 1 = y }} or equivalently {{ x = y + 1 }}
{{ x = 8 }} {{ x = 9 }}
x = x / 2; x = x / 2;
{{ x = 4 }} {{ x = 4 }}
Backward Reasoning
R
Q
{{P}}
{{R}}
S
{{Q}}
Backwards Reasoning Basic Example
{{ [2 - 4(9 + c)] / 7 < 5 }}
a = 9 + c;
{{ (2 - 4a) / 7 < 5 }}
b = 4a;
{{ (2 - b) / 7 < 5 }}
c = 2 - b;
{{ c / 7 < 5 }}
d = c / 7;
{{ d < 5 }}
[2 - 4(9 + c)] / 7 < 5
(2 - 4a) / 7 < 5
(2 - b) / 7 < 5
c / 7 < 5
(input)
2. backwards substitution
(plug and chug)
3. end at the precondition
(output)
Forward & Backward General Rules
Forward Reasoning Tools:
Backward Reasoning Tools:
General:
Simplifying Assertions
{{ [2 - 4(9 + c)] / 7 < 5 }} ←→ {{c > -69 / 4}}
a = 9 + c;
{{ (2 - 4a) / 7 < 5 }}
b = 4a;
{{ (2 - b) / 7 < 5 }}
c = 2 - b;
{{ c / 7 < 5 }}
d = c / 7;
{{ d < 5 }}
[2 - 4(9 + c)] / 7 < 5
(2 - 4a) / 7 < 5
(2 - b) / 7 < 5
c / 7 < 5
{{ original assertion }} ←→ {{ simplified assertion }}
Task 1b & Task 2.a
Try these on your own time! Time estimate: ~20 minutes
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
b) Use forward reasoning to fill in the missing assertions in the following code. Use subscripts or invertible operations.
/*
* 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 2 - Does a Duck Say “Back”?
{{P: x < w + 1 and w > 0}}
{{Q:}}
y = 4 * w
{{ - }}
x = x * 2
{{ - }}
z = x - 8
{{z < y}}
Task 2 - Does a Duck Say “Back”?
b) Use backward reasoning to fill in the missing assertions in the following code:
{{Q:}}
int b = 2 * c
{{ - }}
c = c - 1
{{ - }}
int a = b + 1
{{a >= c}}
return a;
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
{{0 <= s < len and d >= 0}}
int w;
if (s + d <= len) {
{{ - }}
w = d;
{{P1:}}
} else {
{{ - }}
w = len - s;
{{P2:}}
}
{{ - }}
return w;
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?
Rule: while loop
{{ P }}
{{ Inv: I }}
while (b) {
{{ Inv: I and b }}
body
{{ Inv: I }}
}
{{ Inv: I and not b }}
{{ Q }}
The triple {{ P }} while ... {{ Q }} is valid if three checks pass:
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
Fill in P1 using subscripts, then show that the invariant is true when we get to the top of the loop the first time.
{{ x = x_0 and x_0 >= 0 }}
int y = 0;
{{ P1: _________________________ }}
{{ Inv: x_0 - 10y = x and x >= 0 }}
Task 4 - Everybody Loops
c) Check (2):
Fill in Q2 using subscripts (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: _________________________ }}
}
Please turn in your halfsheets!
:)