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.