Homework 2 : Reasoning About Code

Objective
  • To develop techniques based on pre-conditions, post-conditions, and assertions to reason about code.
  • To use weakest preconditions and Hoare Logic to verify code correctness.

Table Of Contents

Directions

  • You may use any standard symbols for “and” and “or” (& and |, && and ||, \(\vee\) and \(\wedge\), etc.)
  • If no precondition is required for a code sequence, write {true} to denote the trivial precondition.
  • You should assume that all numbers are integers, that integer overflow will never occur, and that division is integer division (like in Java, Swift, or Python).

Problems

1. Forward reasoning with assignment statements

Write an assertion in each blank space indicating what is known about the program state, given the precondition and the previously executed statements. Be as specific as possible. The first assertion in part (a) is supplied as an example. Be sure to read the section on renaming variables before starting these problems.

a.  { x > 0 }
    x = 10;
    { x = 10 }
    y = 2 * x;
    {_______________________________ }
    z = y + 4;
    {_______________________________ }
    x = z / 2;
    {_______________________________ }
    y = 0;
    {_______________________________ }

b.  { x > 0 }
    y = x;
    {_______________________________ }
    y = y + 2;
    {_______________________________ }

c.  { |x| > 10 }
    x = -x;
    {_______________________________ }
    x = x / 2;
    {_______________________________ }
    x = x + 1;
    {_______________________________ } 

d.  { y > 2x }
    y = y * 2;
    {_______________________________ }
    x = x + 1;
    {_______________________________ }

2. Backward reasoning with assignment statements

Find the weakest precondition for each sequence using backward reasoning, and write the appropriate assertion in each blank space.

a.  {___________________________}
    x = x + 5;
    {___________________________}
    y = 2 * x;
    { y > 10 }

b.  {___________________________}
    y = x + 6;
    {___________________________}
    z = x + y;
    { z <= 0 }

c.  {___________________________}
    y = w – 10;
    {___________________________}
    x = 2 * x;
    { x > y }

d.  {___________________________}
    t = 2 * s;
    {___________________________}
    r = w + 4;
    {___________________________}
    s = 2*s + w;
    { r > s && s > t }

3. Backward reasoning with if/else statements

Find the weakest precondition for the following conditional statement using backward reasoning, inserting the appropriate assertion in each blank. Be sure to verify that the intermediate postconditions for the two cases imply the total postcondition, i.e. show that (Q1 || Q2) => Q.

{___________________________}
if (x >= 0) {
    {___________________________}
    z = x;
    {___________________________}
} else {
    {___________________________}
    z = x + 1;
    {___________________________}
}
{ z != 0 }

4. Weakest conditions

Identify the weakest condition in each set.

a.  { x = 20 }  { x > 10 }  { x >= 10 }
b.  { t = 2 }  { t != 0 }  { t > 0 }
c.  { x > 0 && y > 0 }  { x > 0 || y > 0 }
d.  { |x+y| > w }  { x+y > w }

5. Hoare triples

State whether each Hoare triple is valid. If it is invalid, explain why and show how you would modify the precondition or postcondition to make it valid.

a.  { x < 0 }
    y = 2*x;
    { y <= 0 }


b.  { x >= y }
    z = x – y;
    { z > 0 }


c.  {true}
    if (x >= 10)
        y = x % 7;
    else
        y = x-1;
    { y < 9}


d.  { x < 0 }
    if (x < 100)
        x = -1;
    else
        x = 1;
    { x < 0 }

6. Verifying correctness

For each block of code, fill in the intermediate assertions, then use them to state whether the precondition is sufficient to guarantee the postcondition. If the precondition is insufficient, explain why and indicate where the assertions don’t match up.

(Hint: for assignment statements, use backward reasoning to find the weakest precondition that guarantees the postcondition, then see if the given precondition is weaker than the weakest precondition. For conditional statements (if), you may find a combination of forward and backward reasoning most useful. Follow the rules given in class for what assertion to insert at each point.)

a.  { x > 0 }
    y = x – 1;
    {___________________________}
    z = 2 * y;
    {___________________________}
    z = z + 1;
    { z > 1 }
    

b.  { 2x >= w }
    y = w – 2;
    {___________________________}
    x = 2*x;
    {___________________________}
    z = x – 2;
    { z >= y }


c.  { y > 0 }
    if (x == y) {
        {___________________________}
        x= -1;
        {___________________________}
    } else {
        {___________________________}
        x = y - 1;
        {___________________________}
    }
    { x < y }

7. Write and prove code

Write a block of code that calculates the smallest even number greater than or equal to x and stores it in y. In other words, y will be assigned either x or x+1. Assume x and y have already been initialized, and annotate your code with assertions before and after each statement to prove that it is correct. At the end of the block, it should be true that y is even and that y equals x or y equals x+1.

Submission

Submit a paper copy of your answers at the beginning of class on the due date.

If you type your solution, you may use any format you like, e.g. plain text, LaTeX, Word, etc. If you’d like to use Markdown, here is a simple template file that you may use to get started.

When answering these questions, clarity is more important than length. The most credit will be given for the most concise, elegant, and complete answers.

Grading Criteria

All homework questions are graded out of five points, roughly as follows:

  • 5: The solution is clear and correct. This solution would easily find a home in a textbook on the subject.
  • 4: The solution contains a few minor mistakes, but they are of little significance overall.
  • 3: The solution hits on the main points, but has at least one major gap in correctness or explanation.
  • 2: The solution contains several mistakes, but parts of it are salvageable.
  • 1: The solution misses the core concepts of the question.
  • 0: No attempt is made at solving the problem.