Closed ifndefJOSH closed 10 months ago
Nagini currently treats all floating point operations as uninterpreted functions, i.e., it essentially knows nothing about what they do and therefore cannot prove anything about them.
I've created a branch with experimental support for interpreted floating point values: https://github.com/marcoeilers/nagini/tree/floats The Nagini version on that branch has an additional command line parameter "--float-encoding=x", where x must be either "real" or "ieee32". So you can verify your example using "--float-encoding=real". Theoretically, "--float-encoding=ieee32" should also work, but reasoning about floating point numbers is incredibly slow, so this may or may not terminate within the next 100 years.
The code isn't properly tested yet, and I'll probably add a warning when uninterpreted floats are used as you suggested.
I tried using the ieee32 option on your example and a few variations and Nagini did actually terminate in ca. 42 minutes, but it could not prove the original example correct. However, this one worked:
def sqr2(num : float) -> float:
Requires(num >= 0.0) # 0.0 instead of 0
Ensures(Result() >= 0.0) # same here
Ensures(num * num == Result())
return num * num
This may mean that I got the encoding from integer literals to floats wrong, or that Z3 is incomplete here; I'll look at it when I have time.
PR #160 is merged now. That means:
--float-encoding=real
and --float-encoding=ieee32
modes are now available in the main branch.
I don't know if this is a "bug" so much as a "limitation", but I figured I'd report it here anyway. Take the simple program
It is evident that
num * num > 0.0
will hold (regardless of the sign ofnum
, although we do restrict it to positive numbers), however the Nagini verifier reports:For comparison, here is a (nearly) equivalent program written in Dafny which does verify:
Now, I'm aware that Dafny's
real
is not an IEEE floating point type, but Python doesn't seem to natively provide a fixed-point type which can be checked. Perhaps Nagini could detect when the type is a float and indicate this might happen?