0

For this piece of code:

  // n is a user input that can be any integer
  s = 0
  i = 0

  while i < n:
    s = s + 1
    i = i + 1

  return s

I would like to prove that the post condition is if n > 0 then s = sum(0, n) else s = 0 where sum(s,e) just adds 1 from s to e exclusive, starting from initial value of 0.

I thought an invariant is if n > 0 and i < n then s = sum(0, i) else s = 0 but I can't get it to be proven in Coq or z3. Any hints?

JRR
  • 6,014
  • 6
  • 39
  • 59

2 Answers2

1

You seem to imply that this algorithm computes the sum but it doesn't actually do that. Instead, it'll count up to n. Perhaps what you intended is:

i = 0
s = 0
while i < n:
  i = i+1
  s = s+i

Note that we increment s by i, not by 1 as in your program.

Assuming this is the intended program, then a good invariant would be:

  • s is the sum of all numbers upto and including i
  • i is at most n

In more programmatic notation:

s == i*(i+1)/2 && i <= n

To see why, remember that the invariant has to hold before and after each loop iteration; and when the loop condition is false, it needs to imply your post-condition. That's why you need the conjunct i <= n, so that when you exit the loop, s will contain the sum indeed.

alias
  • 28,120
  • 2
  • 23
  • 40
  • Thanks. Sorry by sum I really do intend to just count up to n but not adding up all the numbers. Also, I don't think your invariant works since if n < 0 then s will be 0. – JRR Mar 26 '20 at 00:43
  • If you're just counting up, you obviously don't need two variables. In your program, you can easily prove `i = s` at all times. – alias Mar 26 '20 at 01:23
  • I am trying to express the invariant in terms of my `sum` function. – JRR Mar 26 '20 at 01:27
0

How about this solution:

// Function left unimplemented, for simplicity
function sum(s: Int, e: Int): Int
  ensures result == e - s

method foo(n: Int) returns (s: Int)
  requires 0 <= n
{
  var i: Int := 0
  s := 0

  while (i < n)
    invariant s == n - sum(i, n)
  {
    s := s + 1
    i := i + 1
  }
}

Language and tool are called Viper. You can try your example online (the web interface is somewhat slow and unstable), or use the VSCode plugin.

Malte Schwerhoff
  • 12,684
  • 4
  • 41
  • 71