Open JLedelay opened 1 year ago
Reduced:
public class C {
/*@
requires (\exists boolean b; b) ==> guardedCondition;
ensures (\exists boolean b; b) ==> guardedCondition;
@*/
void test(boolean guardedCondition){}
}
Ah, I was under the impression that the array indexing also had an effect, but clearly didn't thoroughly test this. Thanks!
In the first instance, the problem is being caused by the implication being split over its consequent: a ==> b && c
is split as (a ==> b) && (a ==> c)
.
The root cause is in the underlying smt solver (z3). The solver is very good at boolean satisfiability, so a ==> b && c
is normally absolutely equivalent to (a ==> b) && (a == c)
. I suspect however that terms that are not quantifier-free are not treated normally in the sat solver - even when the terms are syntactically identical.
We might want to do an encoding where every quantifier gains an otherwise inaccessible trigger, so that situations like this cause matching quantifiers to trigger each other, e.g.:
/*@
adt triggers {
pure boolean trigger1(boolean b);
}
@*/
public class C {
/*@
requires (\exists boolean b; {:triggers.trigger1(b):} && b) ==> guardedCondition;
ensures (\exists boolean b; {:triggers.trigger1(b):} && b) ==> guardedCondition;
@*/
void test(boolean guardedCondition){}
}
In the meantime, you can also prevent unwanted simplifications by writing a trigger around expressions that you do not want to be split, e.g. (\exists boolean b; b) ==> {: 0 <= y && y < arr[x].f && arr[x].m(y) :}
.
The following input:
Leads to the following output:
The following also result in this error:
(\exists boolean b; b)
(evaluates to true) is replaced with(\exists int j = 0 .. 10; true)
(which evaluates to true) or(\forall boolean b; b)
(which evaluates to false)0 <= y && y < arr[x].f
fromarr[x].m(y)
by putting it in a separate implication, as such:Doing any of the following results in successful verification:
exists
clause(\exists boolean b; b)
with(\exists boolean b; true)
or(\forall boolean b; true)
0 <= y && y < arr[x].f
out of the implication, as such:It looks like the information that
0 <= y && y < arr[x].f
is somehow lost.