-
Notifications
You must be signed in to change notification settings - Fork 55
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
Does not verify syntactic equality #1399
Comments
In this particular case, it is due to underspecifying the type of |
The same problem arises when changing the def foo(key: Boolean): Boolean = false
def bar(l: List[(Boolean, Unit)]): List[(Boolean, Boolean)] = l.map { case (key, keyMapping) => key -> foo(key)}
def barEqualsItsBody(l: List[(Boolean, Unit)]): Unit = {
}.ensuring(bar(l) == (l.map { case (key, keyMapping) => key -> foo(key)})) This time even with an Things I tried while keeping the
|
Mostly commenting my findings so that I do not forget :p x => (x._1, foo(x._1)) For x => {
val y: Boolean = x._1
(y, foo(y))
} hence they are actually not the same from Inox' perspective. |
Hmm, this is a bit surprising. I would expect to see the reverse :P (namely the lambda inside the body of We call stainless/core/src/main/scala/stainless/verification/VerificationChecker.scala Lines 140 to 142 in 33a990a
But we don't perform projection inlining inside We can extend the You can extend the let case here to cover simple expressions: ...
lazy val realPE = ...
lazy val isSimpleBinding = re match {
case TupleSelect(_: Variable, _) | ADTSelector(_: Variable, _) | IsConstructor(_: Variable, _) |
FiniteSet(Seq(), _) | FiniteMap(Seq(), _, _, _) | FiniteBag(Seq(), _) => true
case _ => false
}
if (
(((!inLambda && pe) || (inLambda && realPE && !containsLambda)) && insts <= 1) ||
(!inLambda && immediateCall && insts == 1) ||
(((!inLambda && pe) || (inLambda && realPE)) && isSimpleBinding)
) {
...
(replaceFromSymbols(Map(vd -> re), rb), pe && pb)
... Unrelated, but these lines look a bit suspicious: Doesn't this transformation just get undone by the one below anyway? |
The simplified VC is: bar$0(l$38) == map$9[(Boolean, Unit), (Boolean, Boolean)](l$38, (x$1$8: (Boolean, Unit)) => {
val key$13: Boolean = x$1$8._1
(key$13, foo$0(key$13))
}) which now you mention |
Yeah same here. Might be worth investigating a bit exactly where the simplifications take place.
The issue is that
It seems to lift I think we used to have a simplification which rewrote things like |
Ah right, I've forgot about impure expressions! I'll make these changes, thanks :) |
Regarding For the suspicious line, it appears to worsen simplification in some cases. object Simp {
case class A(b: B, f2: BigInt)
case class B(f1: BigInt, f2: BigInt)
def test(f1: BigInt): Unit = {
val a = A(B(f1, 1), 2)
assert(a.b.f1 == f1)
}
} The original VC is: val a: A = A(B(f1, BigInt("1")), BigInt("2"))
a.b.f1 == f1 With the suspicious line, we get: B(f1, BigInt("1")).f1 == f1 Without it, the expression simplifies to true! val b: B = B(f1, BigInt("1"))
val a: A = A(b, BigInt("2"))
a.b.f1 == f1 The idea sounds good, though it may need some rules to be extended? For the val res: Unit = ()
bar(l) == map[(Boolean, Unit), (Boolean, Boolean)](l, (x: (Boolean, Unit)) => x match {
case (key, keyMapping) =>
(key, foo(key))
}) It's Stainless |
Yes, good idea!
Right. IIRC the convoluted logic with
Haha that's indeed significantly worse :)
I'm not sure the expression we're giving to
Ahh, I see. I forgot we had a Stainless-specific version. Maybe these lines are the true culprit for the issue then: stainless/core/src/main/scala/stainless/transformers/SimplifierWithPC.scala Lines 15 to 19 in 73eb421
We should probably drop them once you've added the simple-binding case to Inox. |
OP hasn't responded to me yet if these changes are still working for him. They do for the test cases I have. |
Stainless timeouts when verifying that
bar
is actually equal to its body.Moreover if we add assertions in the body of the theorem, we have two body assertions timeouts, one for the Cons case and one for the global case, which should not happen.
In Scala 3, the first snippet verifies but there is still the same problem for the second one.
The text was updated successfully, but these errors were encountered: