-2

enter image description here

so, I'm supposed to use the information provided above the loop to figure what the values of n, low, and high are going to be without the need to know what is actually happening inside the loop. Can someone explain how can I use loop invariant to solve this example. The question is to find these values n=81 and low =8 and '''high=9```. These are the correct answers for the question.

1 Answers1

0

We have three axioms:

  • low and high are allowed to change inside the loop, but n is not.
  • low + 1 <= high and low * low < n <= high * high must both be true in each iteration of the loop.
  • high - low must decrease for each iteration of the loop

I'm not sure what your textbook says is the proper method for deriving the output - reference it - but from my perspective, the problem-solving method is thus:

  1. Compare the solution to the initial values
    • n does not change (which is good, the @updates implies it's not supposed to)
    • low increases from 3 to 8
      • note that 8^2 = 64
    • high decreases from 41 to 9
      • note that 9^2 = 81
    • the axioms given in the comment above the loop are maintained here
      • (8 + 1) <= 9
      • 8^2 < 81 <= 9^2
  2. Since the axiom says @decreases high - low, this must be the driving force of change within the loop. Either high must decrease, or low must increase.
    • see that high has decreased, and low has increased. This must be the direction they're individually supposed to change in. Note that doing either of these things will fulfill the @decreases demand, because math.
  3. The @maintains axioms define the limits of this change. low cannot exceed high (and low * low cannot exceed n), and high * high cannot ever be less than n.
    • i.e. when to stop changing low or high. If a change would violate one of these, then don't make that change.

We can conclude that the intention of this loop is to set low and high such that

  • they differ by exactly 1
  • n is between low^2 and high^2 (inclusive of high^2)

or, in other words, to set low and high respectively to the two roots of the perfect squares which n sits between.


From this, we can write the following code:

while (low < high - 1) {  // will terminate when low == high - 1
    // check the @maintains for `low`. The first @maintains was just checked by the
    // loop, so we just have to check the next @maintains. If increasing `low`
    // would not make the @maintains false, then we can increase `low`.
    if ((low + 1) * (low + 1) < n) {  
        low++;    // this will always decrease the value of (high - low), per @decreases
    }
    // check the @maintains for `high`. Same as above, but since `low` might
    // have changed since the last time we checked, we need to double-check
    // that we can still decrease high without problems.
    if ((high - 1) * (high - 1) >= n && (high - 1) > low) {
        high--;   // this will always decrease the value of (high - low), per @decreases
    }
}
Green Cloak Guy
  • 23,793
  • 4
  • 33
  • 53
  • The question is to find these values ``` n=81``` and ```low =8``` and '''high=9```. These are the correct answers for the question. What are the steps to find these answers? – The highlight Aug 03 '21 at 04:35