Open DavePearce opened 6 years ago
Further reducing the verification to this does help, though it still takes a while to get through them all:
assert:
forall(int[] ns, int[] ns$1, nat i$1, nat i$2):
if:
i$1 < |ns$1|
then:
forall(int k):
if:
(0 <= k)
(k < i$2)
then:
ns[k] == 0
This definitely suggests that a better approach to handling the state space is required.
IDEA 1: One idea here is to instantiate variables for iteration lazily. That is, at the point of use of a variable we then (somehow) instantiate an iteration space for that variable. This would be very helpful for functions as well (#142) since they don't have explicit declaration points where we can iterate.
IDEA 2: The other obvious idea is to perform integer range analysis on declared types to determine upper and lower bounds. This would be particularly good for e.g. nat
types which are common.
Note that idea 1 may have some advantages with situations like this:
forall(int i, int j):
if:
i == j + 1
then:
...
Here, we don't want to iterate all of i
's space as it is fully determined by j
's.
For some reasons, counterexample generation seems to timeout quite easily. Not sure what's going on there. This is the smallest example I've found so far:
The offending verification condition is:
This can then be reduced to this whilst preserving the timeout:
One of the obvious things to note here is the number of quantifier parameters. That is despite the fact that most of them are not even used!