Skip to content

Inconsistent behavior of division #297

Open
@viper-admin

Description

@viper-admin

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmajor

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions