Open
Description
Created by bitbucket user robinsierra on 2019-11-05 13:29
Last updated on 2020-02-06 13:09
The two backends produce different behavior for division. The following Viper program verifies in Silicon but not in Carbon
method foo(a: Int, b: Int)
requires a == 12 && b == 5
{
assert 12 / 5 == 2
assert -12 / -5 == 3 // carbon: -12 / -5 == 2 works
assert 12 / -5 == -2
assert -12 / 5 == -3 // carbon: -12 / 5 == -2 works
assert a / -b == -2
assert -a / b == -3
assert -a / -b == 3
}
while the slightly modified version
method foo(a: Int, b: Int)
requires a == 12 && b == 5
{
assert 12 / 5 == 2
assert -12 / -5 == 2 // silicon: -12 / -5 == 3 works
assert 12 / -5 == -2
assert -12 / 5 == -2 // silicon: -12 / 5 == -3 works
assert a / -b == -2
assert -a / b == -3
assert -a / -b == 3
}
works in Carbon but not Silicon. Carbon is in itself inconsistent though, as -12 / 5 is -2 for literals (evaluated statically?) but -3 for symbolic values.
In general, what kind of integer division does Viper do? If it does floor division (like Python) or truncating divison (like Java and C) both Silicon and Carbon give incorrect results for some negative values, if it just uses z3’s division the problem is only in Carbon.