# Lecture 1: Contracts

## Question 1 (Hard)

Consider the following piece of code.

```
int foo()
//@ensures ???
{
int x = 0;
for (int i = 0; i <= 10; i++)
//@loop_invariant ???
{
x += POW(2, i);
}
return x;
}
```

What is a possible loop invariant we could use to prove the correctness of the loop?

What is a loop invariant we could use for termination? What will the final value of be?

**Solution**

```
//@loop_invariant i <= 0 && i <= 11;
//@loop_invariant x == POW(2, i) - 1;
```

The final value of will be `POW(2, 11) - 1`

## Question 2 (Medium)

*Addresses learning objectives (1)(4)*

Given the following contracts and function name, write a function which works as expected.

```
int divmod (int a, int b)
//@requires b != 0;
//@ensures \result[0] * b + \result[1] == a;
```

**Solution**

```
int divmod (int a, int b)
//@requires b != 0;
//@ensures \result[0] * b + \result[1] == a;
{
return [a / b, a % b];
}
```

## Question 3 (Medium)

*Addresses learning objectives (1)(2)(3)(4)(5)(6)*

Given the following `slowGCD`

and `GCD`

function, that takes in two non-negative integers and returns the greatest common divisor of them, prove the correctness of `GCD`

, assuming `slowGCD`

is proven correct.

Do so by proving the initialization, preservation, termination, and correctness of the loop invariants in `GCD`

. You can assume basic properties about the greatest common divisor. For example, by the Euclidean Algorithm, .

```
#use <conio>
#use <util>
int slowGCD(int a, int b)
//@requires 0 <= a && 0 <= b;
{
if(a == 0 || b == 0)
return max(a, b);
//@assert(0 < a && 0 < b);
int index = 1;
int high = 1; //Keeps track of highest common divisor
while(index <= a && index <= b)
//@loop_invariant 1 <= index;
//@loop_invariant index <= max(a, b) + 1;
{
if(a % index == 0 && b % index == 0) //index is a common divisor
high = index;
index++;
}
return high;
}
// Note by the Euclidean algorithm
int GCD(int a, int b)
//@requires 0 <= a && 0 <= b;
//@ensures slowGCD(a, b) == \result;
{
int x = a;
int y = b;
while(x != 0 && y != 0)
//@loop_invariant slowGCD(x, y) == slowGCD(a, b);
//@loop_invariant 0 <= x && 0 <= y;
{
if(x > y)
x = x - y;
else
y = y - x;
}
return max(x, y);
}
```