With a sample find.c file, I can prove it with no problem using default alt-ergo. But when change to cvc4 then getting warning messages and syntax error. Here the code:
/*# requires 0 <= n && \valid(a+(0..n-1));
assigns \nothing;
ensures (\result == -1 && ! (\exists int i; 0<=i<n && a[i] == v))
|| (0 <= \result < n && a[\result] == v);
*/
int find(int n,const int a[n],int v)
{
int i;
/*# loop invariant 0<=i<=n;
loop invariant \forall int j; 0<=j<i ==> a[j] != v;
loop assigns i;
loop variant n - i;
*/
for (i=0; i<n; ++i)
if (a[i] == v)
return i;
return -1;
}
int main(void)
{
const int const a1[5] = { 9,7,8,9,6 };
int const f1 = find(5,a1,8);
return 0;
}
Run this command and get these messages:
frama-c -wp -wp-prover CVC4 -wp-out out find.c
File "out/typed/find_Why3_ide.why", line 14, characters 0-20:
warning: the keyword `import' is redundant here and can be omitted
File "out/typed/find_Why3_ide.why", line 15, characters 0-28:
warning: the keyword `import' is redundant here and can be omitted
File "out/typed/Compound.why", line 6, characters 0-20:
warning: the keyword `import' is redundant here and can be omitted
File "out/typed/Compound.why", line 7, characters 0-18:
warning: the keyword `import' is redundant here and can be omitted
File "out/typed/Compound.why", line 8, characters 0-31:
warning: the keyword `import' is redundant here and can be omitted
File "out/typed/Compound.why", line 9, characters 0-25:
warning: the keyword `import' is redundant here and can be omitted
File "out/typed/Compound.why", line 10, characters 0-18:
warning: the keyword `import' is redundant here and can be omitted
File "out/typed/Compound.why", line 12, characters 0-18:
warning: the keyword `import' is redundant here and can be omitted
File "out/typed/Compound.why", line 13, characters 0-24:
warning: the keyword `import' is redundant here and can be omitted
File "out/typed/find_Why3_ide.why", line 17, characters 60-61:
syntax error
------------------------------------------------------------
[wp] [CVC4] Goal typed_find_loop_inv_2_preserved : Failed
Why3 exits with status 1.
[wp] [CVC4] Goal typed_find_loop_inv_preserved : Failed
Why3 exits with status 1.
[wp] [CVC4] Goal typed_find_post : Failed
Why3 exits with status 1.
[wp] Proved goals: 10 / 13
Qed: 10 (4ms)
CVC4: 0 (failed: 3)
How to get rid of the warnings and syntax error? My CVC4 is version 1.6.
Related
I have to script a pascal code that rations into calculation the frequency of a character's appearance in the code and displays it through the output mode
Input P2 changes:
Second Attempt at the coding phase
I tried revisioning the code.I added the output variable writeln('input array of characters'); & writeln('Number of Occurrences',k);, which should help me output how many times did the S character appear overall in the code, plus utilised the for & if commands to have the final values showcased based on the conditions, if the frequency is 1 then count in S, still getting errors, take a look at the Input P2 & Output P2
Input P1
function Count(t, s: String): Integer;
var
Offset, P: Integer;
begin
Result := 0;
Offset := 1;
P := PosEx(t, s, Offset);
while P > 0 do
begin
Inc(Result);
P := PosEx(t, s, P + 1);
end;
end;
Output P2
Target OS: Linux for x86-64
Compiling main.pas
main.pas(5,3) Error: Identifier not found "Result"
main.pas(7,8) Error: Identifier not found "PosEx"
main.pas(8,3) Error: Identifier not found "unsigned"
main.pas(8,12) Fatal: Syntax error, ";" expected but "identifier N" found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
-------------------------------------------------------------------
Input P2
program p1
var S:string
i:integer
begin
writeln('input array of characters');
k:=O;
for i:=1 to length (S) do
if (S[i])='m') and (S[i+1]='a') then k:=k+1;
writeln('Number of Occurrences',k);
Readln;
end.
Output P2
Compiling main.pas
main.pas(2,1) Fatal: Syntax error, ";" expected but "VAR" found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
The errors you see in the first block:
Identifier not found "Result"
Standard Pascal doesn't recognize the pseudovariable Result. In some Pascal implementations (like e.g. Delphi) it can be used to assign a value to the function result. The Pascal you are using needs to have the result of a function assigned to the name of the function. For example:
function Whatever(): integer;
begin
Whatever := 234;
end;
Identifier not found "PosEx"
Not all Pascal implementations include the PosEx() function. You need to use Pos() instead. But, the standard implementation of Pos() doesn't include the "search start position" that PosEx has. Therefore you need to ditch Pos() and do as you do in "Input P2", that is traverse the text character per character and count the occurances as you go.
Identifier not found "unsigned"
Seems you have removed that unknown identifier.
The error you see in the second block:
In Output P2 the error message should be clear. You are missing a semicolon where one is needed. Actually you are missing three of them.
You are also missing the line that reads user input: ReadLn(S);.
Finally, to calculate both upper and lower case characters you can use an extra string variable, say SU: string to which you assign SU := UpperCase(S) after reading user input, and then use that string to count the occurances.
I think this is more like what you want to do:
function Count(t, s: String): Integer;
var
Offset,Res, P: Integer;
begin
Res := 0
Offset := 1;
repeat
P := Pos(t, s, Offset);
if p>0 then
Inc(Res);
Offset := P+1
untl P = 0;
Count := Res;
end;
Now, if you don't have Pos, you can implement it:
Function Pos(const t,s:string; const Start:integer):Integer;
Var
LS, LT, {Length}
IxS, IxT, {Index)
R: Integer; {Result}
begin
R := 0;
{use only one of the two following lines of code}
{if your compiler has length}
LS := length(S); LT := Length(T);
{If it does not}
LS := Ord(s[0]); LT := Ord(T[0]);
if (LS <= LT) {if target is larger than search string, it's not there}
and (Start<=LT) and {same if starting position beyond size of S}
(Start+LT <-LS) then {same if search would go beyond size of S}
begin {Otherwise, start the search}
ixT := 1;
ixS := Start;
repeat
Inc(R); {or R:= R+1; if INC not available }
If (S[ixS] <> T[ixT]) then
R := 0 {they don't match, we're done}
else
begin {Move to next char}
Inc(ixS);
Inc(ixT);
end;
until (R=0) or (ixT>LT); {if search failed or end of target, done}
Pos := R;
end;
I would like to create a function in SPARK_Mode that utilizes the GNAT GCC intrinsic function "__builtin_ctzll".
with Interfaces; use Interfaces;
package GCC_Intrinsic with
SPARK_Mode
is
function DividesLL (A, B : Unsigned_64) return Boolean is (B mod A = 0) with
Ghost,
Pre => A /= 0;
function CTZLL (X : Unsigned_64) return Natural with
Pre => X /= 0,
Post => CTZLL'Result in 0 .. Unsigned_64'Size - 1
and then DividesLL (Unsigned_64 (2)**CTZLL'Result, X)
and then
(for all Y in CTZLL'Result + 1 .. Unsigned_64'Size - 1 =>
not DividesLL (Unsigned_64 (2)**Y, X));
pragma Import (Intrinsic, CTZLL, "__builtin_ctzll");
end GCC_Intrinsic;
I would like to assume the postcondition to be true since it is the definition of the number of trailing zeros which is implied by the documentation. However, I am unsure how to accomplish this, having read much documentation and having tried to use "pragma Assume". I am relatively new to Ada/SPARK and am using GNAT Community 2020. Can someone please help me solve this issue so that gnatprove is able to prove the postcondition of CTZLL?
When I formulate the postcondition (contract) of __builtin_ctzll using Shift_Right, I'm able proof (using GNAT CE 2020 and proof level 1) that test.adb is free of run-time errors if it would be run.
Note: Related documentation: SPARK user's manual, section 7.4.5: Writing Contracts on Imported Subprograms.
intrinsic.ads
pragma Assertion_Policy (Check);
with Interfaces; use Interfaces;
package Intrinsic with SPARK_Mode is
-- Count Trailing Zeros (long long unsigned).
function CTZLL (X : Unsigned_64) return Natural with
Pre => X /= 0,
Post => CTZLL'Result in 0 .. Unsigned_64'Size - 1 and
(for all I in 0 .. CTZLL'Result - 1 =>
(Shift_Right (X, I) and 2#1#) = 2#0#) and
(Shift_Right (X, CTZLL'Result) and 2#1#) = 2#1#;
-- You could also use aspects (Import, Convention, External_Name).
pragma Import (Intrinsic, CTZLL, "__builtin_ctzll");
end Intrinsic;
test.adb
pragma Assertion_Policy (Check);
with Interfaces; use Interfaces;
with Intrinsic; use Intrinsic;
procedure Test with SPARK_Mode is
begin
-- Absence of Run-Time Errors (AoRTE) for this program can be proven:
-- Assert_Failure will not be raised at runtime.
pragma Assert (CTZLL ( 1) = 0);
pragma Assert (CTZLL ( 2) = 1);
pragma Assert (CTZLL ( 3) = 0);
pragma Assert (CTZLL ( 4) = 2);
pragma Assert (CTZLL ( 5) = 0);
pragma Assert (CTZLL ( 6) = 1);
pragma Assert (CTZLL ( 7) = 0);
pragma Assert (CTZLL ( 8) = 3);
pragma Assert (CTZLL ( 9) = 0);
pragma Assert (CTZLL (10) = 1);
pragma Assert (CTZLL (2 ** 63 ) = 63);
pragma Assert (CTZLL (2 ** 64 - 1) = 0);
end Test;
output (of gnatprove)
$ gnatprove -P default.gpr -j0 -u test.adb --level=1 --report=all
Phase 1 of 2: generation of Global contracts ...
Phase 2 of 2: flow analysis and proof ...
test.adb:12:19: info: precondition proved
test.adb:12:19: info: assertion proved
[...]
test.adb:24:19: info: precondition proved
test.adb:24:19: info: assertion proved
For those not familiar with __builtin_ctzll: returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined. See also here. Example:
main.adb
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Interfaces; use Interfaces;
with Intrinsic; use Intrinsic;
procedure Main is
begin
for K in 1 .. 10 loop
Put (K, Width => 3);
Put (K, Width => 9, Base => 2);
Put (CTZLL (Unsigned_64 (K)), Width => 4);
New_Line;
end loop;
end Main;
output (of Main)
$ ./obj/main
1 2#1# 0
2 2#10# 1
3 2#11# 0
4 2#100# 2
5 2#101# 0
6 2#110# 1
7 2#111# 0
8 2#1000# 3
9 2#1001# 0
10 2#1010# 1
I have a simple kernel in OpenCL that has the following structure:
kernel void simple_select(global double *input, global double *output) {
size_t i = get_global_id(0);
printf("input %d\n", (int)(input[i] != 0.0));
output[i] = select((float)0.0, (float)1.0, (int)(input[i] != 0.0));
//output[i] = select((float)0.0, (float)1.0, 1);
}
Equivalently this can be:
kernel void simple_select(global double *input, global double *output) {
size_t i = get_global_id(0);
printf("input %d\n", (int)(input[i] != 0.0));
output[i] = input[i] != 0.0 ? 1.0 : 0.0;
//output[i] = 1 ? 1.0 : 0.0;
}
When I print to the command line, I see:
input 1
input 1
input 1
But the output array has all 0.0. However, if I uncomment the last line of the kernel and comment out the second-to-last-line (meaning if I use the scalar 1 in the select statement) then it works as expected and the output array has all 1.0. So what is the difference between these two lines that leads to two different results?
Here is the answer.
It's a quirk in OpenCL. The problem is that true/false values for scalars are 1/0 (like printf has shown you), but true/false values for vectors are -1/0 - and this is also what select() expects in last argument (more precisely, it expects MSB set which means any negative integer).
Though i think the ternary operator on scalars should still work as expected, if it doesn't i would consider it a bug.
I have installed frama-c using opam and homebrew, following the instructions from the frama-c site. I'm on Mac OS X (El Capitan), and the versions are:
frama-c: Magnesium-20151002
alt-ergo: 1.01
ocaml: 4.02.3
When I attempt to run with the swap.c tutorial, it fails to verify. Here's the error I get:
[ frama-c ]> frama-c -wp -wp-out temp swap.c swap1.h
[kernel] Parsing FRAMAC_SHARE/libc/__fc_builtin_for_normalization.i (no preprocessing)
[kernel] Parsing swap.c (with preprocessing)
[kernel] Parsing swap1.h (with preprocessing)
[wp] warning: Missing RTE guards
[wp] 2 goals scheduled
------------------------------------------------------------
--- Alt-Ergo (stdout) :
------------------------------------------------------------
File "temp/typed/swap_post_A_Alt-Ergo.mlw", line 786, characters 1-299:Valid (0.0093) (12 steps)
------------------------------------------------------------
[wp] [Alt-Ergo] Goal typed_swap_post_A : Failed
Error: Can not understand Alt-Ergo output.
[wp] Proved goals: 1 / 2
Qed: 1
Alt-Ergo: 0 (failed: 1)
The output message seems to suggest that alt-ergo could prove the assertion, but then frama-c could not parse the output. Could this be because the alt-ergo version is too new? Here is the goal on line 786 of the generated file, referenced in the above output:
goal swap_post_A:
forall t : (addr,int) farray.
forall a_1,a : addr.
let x = t[a] : int in
let x_1 = t[a_1] : int in
let x_2 = t[a_1 <- x][a <- x_1][a_1] : int in
is_sint32(x) ->
is_sint32(x_1) ->
(region(a.base) <= 0) ->
(region(a_1.base) <= 0) ->
is_sint32(x_2) ->
(x = x_2)
If I run alt-ergo on this generated file directly, it returns with code 0.
I'm working on a arduino(uno) talking clock project. I'm using the code on this site : https://learn.adafruit.com/wave-shield-talking-clock/overview
add the WaveHC library when I get the following error :
Arduino:1.6.6 (Windows 10), Card:"Arduino/Genuino Uno"
TalkingClock:44: error: no matching function for call to 'WaveHC::WaveHC()'
WaveHC wave;
^
\Arduino\TalkingClock\TalkingClock.ino:44:12: note: candidates are:
In file included from \Arduino\TalkingClock\TalkingClock.ino:26:0:
\Arduino\libraries\WaveHC/WaveHC.h:113:3: note: WaveHC::WaveHC(HardwareSerial&)
WaveHC(HardwareSerial& serial);
^
\Arduino\libraries\WaveHC/WaveHC.h:113:3: note: candidate expects 1 argument, 0 provided
\Arduino\libraries\WaveHC/WaveHC.h:77:7: note: constexpr WaveHC::WaveHC(const WaveHC&)
class WaveHC
^
\Arduino\libraries\WaveHC/WaveHC.h:77:7: note: candidate expects 1 argument, 0 provided
\Arduino\libraries\WaveHC/WaveHC.h:77:7: note: constexpr WaveHC::WaveHC(WaveHC&&)
\Arduino\libraries\WaveHC/WaveHC.h:77:7: note: candidate expects 1 argument, 0 provided
TalkingClock:64: error: variable 'hours' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
*hours[] = { h12, h01, h02, h03, h04, h05, h06, h07, h08, h09, h10, h11 },
^
TalkingClock:65: error: variable 'mTens' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
*mTens[] = { m00, m10, m20, m30, m40, m50 },
^
TalkingClock:66: error: variable 'mTeens' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
*mTeens[] = { m11, m12, m13, m14, m15, m16, m17, m18, m19 },
^
TalkingClock:67: error: variable 'mTenX' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
*mTenX[] = { m0x, NULL, m2x, m3x, m4x, m5x },
^
TalkingClock:68: error: variable 'mins' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
*mins[] = { m1, m2, m3, m4, m5, m6, m7, m8, m9 },
^
TalkingClock:69: error: variable 'ampm' must be const in order to be put into read-only section by means of '__attribute__((progmem))'
*ampm[] = { am, pm };
^
exit status 1
no matching function for call to 'WaveHC::WaveHC()'