I’ve noticed that SPARK doesn’t seem to know the properties of the Width attribute, or there is something that I’m missing.
with Ada.Text_IO;
procedure Image_Width with SPARK_Mode is
function Image (Number : Integer) return String
with Post => Image'Result'Length <= Integer'Width;
function Image (Number : Integer) return String is
begin
return Integer'Image (Number);
end Image;
begin
Ada.Text_IO.Put_Line (Image (123));
Ada.Text_IO.Put_Line (Integer'Last'Image'Length'Image);
Ada.Text_IO.Put_Line (Integer'First'Image'Length'Image);
end Image_Width;
When it is run:
123
11
11
When passed to gnatprove:
alr exec -- gnatprove -P /home/mgr/tmp/image_width/image_width.gpr -j0 -u image_width.adb -cargs -gnatef
QSocketNotifier: Can only be used with threads started with QThread
Phase 1 of 3: generation of data representation information ...
Phase 2 of 3: generation of Global contracts ...
Phase 3 of 3: flow analysis and proof ...
/home/mgr/tmp/image_width/src/image_width.adb:6:19: medium: postcondition might fail
6 | with Post => Image'Result'Length <= Integer'Width;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Summary logged in /home/mgr/tmp/image_width/obj/development/gnatprove/gnatprove.out
I’m using gnatprove from Alire (14.1.1).
Shouldn’t SPARK know the properties of the Image and Width arguments? Isn’t my postcondition a direct consequent of the definition of those attributes?
Moreover, if I simply add + 1
, that is, changing:
with Post => Image'Result'Length <= Integer'Width;
to
with Post => Image'Result'Length <= Integer'Width + 1;
Then gnatprove gives its green light. Is this a bug in gnatprove or is there some special case where the length of Integer’Image can be 12?