-
Notifications
You must be signed in to change notification settings - Fork 274
Supports quantifiers in function contracts #5959
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// clang-format off | ||
int f1(int *arr) __CPROVER_requires(__CPROVER_exists { | ||
int i; | ||
(0 <= i && i < 8) ==> arr[i] == 0 | ||
}) __CPROVER_ensures(__CPROVER_exists { | ||
int i; | ||
(0 <= i && i < 8) ==> arr[i] == 0 | ||
}) | ||
// clang-format on | ||
{ | ||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int arr[8]; | ||
f1(arr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
CORE | ||
main.c | ||
--enforce-all-contracts | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_exists | ||
in a negative context (which is currently not always the case). By using the | ||
--enforce-all-contracts flag, this test assumes the statement in | ||
__CPROVER_requires, then asserts the same statement (in __CPROVER_ensures), | ||
thus, verification should be successful. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// clang-format off | ||
int f1(int *arr, int *len) __CPROVER_requires(__CPROVER_exists { | ||
int i; | ||
(0 <= i && i < len) ==> arr[i] == 0 | ||
}) __CPROVER_ensures(__CPROVER_exists { | ||
int i; | ||
(0 <= i && i < len) ==> arr[i] == 0 | ||
}) | ||
// clang-format on | ||
{ | ||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int len, arr[8]; | ||
f1(arr, len); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
KNOWNBUG | ||
main.c | ||
--enforce-all-contracts | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_exists | ||
in a negative context (which is currently not always the case). By using the | ||
--enforce-all-contracts flag, this test assumes the statement in | ||
__CPROVER_requires, then asserts the same statement (in __CPROVER_ensures), | ||
thus, verification should be successful. | ||
|
||
Known bug: | ||
The current implementation cannot handle a structure such as | ||
__CPROVER_assume(__CPROVER_exists(int i; pred(i))), where i is | ||
not explicitly bounded to a predefined range (i.e. if at least | ||
one of its bound is only declared and not defined). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you tried the SMT back-end? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// clang-format off | ||
int f1(int *arr) __CPROVER_ensures(__CPROVER_exists { | ||
int i; | ||
(0 <= i && i < 10) ==> arr[i] == i | ||
}) | ||
// clang-format on | ||
{ | ||
for(int i = 0; i < 10; i++) | ||
{ | ||
arr[i] = i; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int arr[10]; | ||
f1(arr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CORE | ||
main.c | ||
--enforce-all-contracts | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_exists | ||
in __CPROVER_ensures clauses. By using the --enforce-all-contracts flag, | ||
goto-instrument will transform the __CPROVER_ensures clauses into an | ||
assertion and the verification remains sound when using __CPROVER_exists. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// clang-format off | ||
int f1(int *arr) __CPROVER_ensures(__CPROVER_exists { | ||
int i; | ||
(0 <= i && i < 10) ==> arr[i] != 0 | ||
}) | ||
// clang-format on | ||
{ | ||
for(int i = 0; i < 10; i++) | ||
{ | ||
arr[i] = 0; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int arr[10]; | ||
f1(arr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
KNOWNBUG | ||
main.c | ||
--enforce-all-contracts | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
^VERIFICATION FAILED$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_exists | ||
in __CPROVER_ensures clauses. By using the --enforce-all-contracts flag, | ||
goto-instrument will transform the __CPROVER_ensures clauses into an | ||
assertion and the verification remains sound when using __CPROVER_exists. | ||
|
||
Known Bug: | ||
We expect verification to fail because arr[i] is always equal to 0 for | ||
[0 <= i < 10]. In fact, we expect the (0 <= i && i < 10) statement to act as a | ||
range for i. However, in the current implementation of quantifier handling, | ||
the (0 <= i && i < 10) statement is not interpreted as an explicit range, but | ||
instead, as part of a logic formula, which causes verification to succeed. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// clang-format off | ||
int f1(int *arr) __CPROVER_requires(__CPROVER_exists { | ||
int i; | ||
(0 <= i && i < 10) ==> arr[i] == 4 | ||
}) __CPROVER_ensures(__CPROVER_return_value == 0) | ||
// clang-format on | ||
{ | ||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; | ||
f1(arr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CORE | ||
main.c | ||
--replace-all-calls-with-contracts | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_exists | ||
in __CPROVER_requires clauses. By using the --replace-all-calls-with-contracts | ||
flag, goto-instrument will transform the __CPROVER_requires clauses into an | ||
assertion and the verification remains sound when using __CPROVER_exists. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// clang-format off | ||
int f1(int *arr) __CPROVER_requires(__CPROVER_exists { | ||
int i; | ||
(0 <= i && i < 10) ==> arr[i] == 1 | ||
}) __CPROVER_ensures(__CPROVER_return_value == 0) | ||
// clang-format on | ||
{ | ||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int arr[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | ||
f1(arr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
KNOWNBUG | ||
main.c | ||
--replace-all-calls-with-contracts | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
^VERIFICATION FAILED$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_exists | ||
in __CPROVER_requires clauses. By using the --replace-all-calls-with-contracts | ||
flag, goto-instrument will transform the __CPROVER_requires clauses into an | ||
assertion and the verification remains sound when using __CPROVER_exists. | ||
|
||
Known Bug: | ||
We expect verification to fail because arr[i] is never equal to 1 for | ||
[0 <= i < 10]. In fact, we expect the (0 <= i && i < 10) statement to act as a | ||
range for i. However, in the current implementation of quantifier handling, | ||
the (0 <= i && i < 10) statement is not interpreted as an explicit range, but | ||
instead, as part of a logic formula, which causes verification to succeed. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// clang-format off | ||
int f1(int *arr) __CPROVER_requires(__CPROVER_forall { | ||
int i; | ||
(0 <= i && i < 8) ==> arr[i] == 0 | ||
}) __CPROVER_ensures(__CPROVER_forall { | ||
int i; | ||
(0 <= i && i < 8) ==> arr[i] == 0 | ||
}) | ||
// clang-format on | ||
{ | ||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int arr[8]; | ||
f1(arr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
CORE | ||
main.c | ||
--enforce-all-contracts | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_forall | ||
in a negative context (which is currently not always the case). By using the | ||
--enforce-all-contracts flag, this test assumes the statement in | ||
__CPROVER_requires, then asserts the same statement (in __CPROVER_ensures), | ||
thus, verification should be successful. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// clang-format off | ||
int f1(int *arr, int len) __CPROVER_requires(__CPROVER_forall { | ||
int i; | ||
(0 <= i && i < len) ==> arr[i] == 0 | ||
ArenBabikian marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}) __CPROVER_ensures(__CPROVER_forall { | ||
int i; | ||
(0 <= i && i < len) ==> arr[i] == 0 | ||
}) | ||
// clang-format on | ||
{ | ||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int len, arr[8]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Such a case is already tested for in the |
||
f1(arr, len); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
KNOWNBUG | ||
main.c | ||
--enforce-all-contracts | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_forall | ||
in a negative context (which is currently not always the case). By using the | ||
--enforce-all-contracts flag, this test assumes the statement in | ||
__CPROVER_requires, then asserts the same statement (in __CPROVER_ensures), | ||
thus, verification should be successful. | ||
|
||
Known bug: | ||
The current implementation cannot handle a structure such as | ||
__CPROVER_assume(__CPROVER_forall(int i; pred(i))), where i is | ||
not explicitly bounded to a predefined range (i.e. if at least | ||
one of its bound is only declared and not defined). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// clang-format off | ||
int f1(int *arr) __CPROVER_ensures(__CPROVER_forall { | ||
int i; | ||
(0 <= i && i < 10) ==> arr[i] == 0 | ||
}) | ||
// clang-format on | ||
{ | ||
for(int i = 0; i < 10; i++) | ||
{ | ||
arr[i] = 0; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int arr[10]; | ||
f1(arr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CORE | ||
main.c | ||
--enforce-all-contracts | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_forall | ||
in __CPROVER_ensures clauses. By using the --enforce-all-contracts | ||
flag, goto-instrument will transform the __CPROVER_ensures clauses into an | ||
assertion and the verification remains sound when using __CPROVER_forall. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// clang-format off | ||
int f1(int *arr) __CPROVER_ensures(__CPROVER_forall { | ||
int i; | ||
(0 <= i && i < 10) ==> arr[i] == i | ||
}) | ||
// clang-format on | ||
{ | ||
for(int i = 0; i < 10; i++) | ||
{ | ||
if(i == 0) | ||
arr[i] = -1; | ||
else | ||
arr[i] = i; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int arr[10]; | ||
f1(arr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CORE | ||
main.c | ||
--enforce-all-contracts | ||
^EXIT=10$ | ||
^SIGNAL=0$ | ||
^VERIFICATION FAILED$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_forall | ||
in __CPROVER_ensures clauses. By using the --enforce-all-contracts | ||
flag, goto-instrument will transform the __CPROVER_ensures clauses into an | ||
assertion and the verification remains sound when using __CPROVER_forall. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// clang-format off | ||
int f1(int *arr) __CPROVER_requires(__CPROVER_forall { | ||
int i; | ||
(0 <= i && i < 10) ==> arr[i] == i | ||
}) __CPROVER_ensures(__CPROVER_return_value == 0) | ||
// clang-format on | ||
{ | ||
return 0; | ||
} | ||
|
||
int main() | ||
{ | ||
int arr[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; | ||
f1(arr); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CORE | ||
main.c | ||
--replace-all-calls-with-contracts | ||
^EXIT=0$ | ||
^SIGNAL=0$ | ||
^VERIFICATION SUCCESSFUL$ | ||
-- | ||
-- | ||
The purpose of this test is to ensure that we can safely use __CPROVER_forall | ||
in __CPROVER_requires clauses. By using the --replace-all-calls-with-contracts | ||
flag, goto-instrument will transform the __CPROVER_requires clauses into an | ||
assertion and the verification remains sound when using __CPROVER_forall. |
Uh oh!
There was an error while loading. Please reload this page.