简体   繁体   中英

Dafny - Fitting digits of a number into an array

I am trying to verify a code that uses simple modulo operation in a while loop to insert the digits of a number into an array.

I recieve a number, an array with defined size, and start - an index in the array from which I fit the most significant digit.

ie if n=123, a = [w,x,y,z], start=0 then I need to create an array [1,2,3] and then fit it into a: [1,2,3,z]

I start by enforcing that the count of number digits (3 in our example) + the starting index do not exceed the bounds of the target array a.

If it doesn't exceed the bounds, I start slicing the number into digits:

var i:nat := (start + nLength - 1);
var n':=n;

while (i>=start && i>0)
decreases i
****invariant *********
{
    a[i] := (n' % 10);
    i := i - 1;
    n' := n' / 10;
}

I am unable to find the right invariant to enfroce the correctness of the loop I made to iterate over the number and split it into digits. Any suggestions?

Let me help you with a possible invariant. It looks like this invariant holds, but I was not able to prove it. Probably it requires more engineering.


function computeNumber(a: seq<int>, startIncluded: int, endExcluded: int, multiplier: int): int
  decreases endExcluded - startIncluded
  requires 0 <= startIncluded <= endExcluded <= |a|
  requires startIncluded >= endExcluded
{
  if startIncluded >= endExcluded then 0
  else a[startIncluded]*multiplier + computeNumber(a, startIncluded+1, endExcluded, multiplier/10)
}

...

  var endExcluded := start + nLength;
  var i:int := endExcluded;
  var n':=n;
  ghost var tenPower := 1;
  ghost var remainder := 0;
  while n' > 0 && i > 0
    decreases i
    invariant n == n' * tenPower + remainder
    invariant computeNumber(a[..], i, endExcluded, tenPower) == remainder
  {
    i := i - 1;
    var digit := n' % 10;
    a[i] := digit;
    n' := n' / 10;    
    remainder := digit * tenPower + remainder;    
    tenPower := tenPower * 10;
  }
  if n' == 0 && i >= 0 {
    assert n == remainder;
    assert computeNumber(a[..], i, endExcluded, tenPower) == n;
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM