You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, inline defs are kept and verified like normal functions and their use appers verified a bit as if annotated by @inlineOnce. However, it would be relatively simple and useful to give users other options.
[ Error ] Test.scala:8:14:Can't inline opaque or extern function, use @inlineOnce instead
inlinedefg(x: BigInt) = {
However, it seems useful for orthogonality of verification to treat g as opaque, so it would be good to
support opaque annotation on inline, with the effect same as if the def was not inline
In the other direction, there is an opportunity to treat inline functions as transparent, as receipies for code and verification that should be applied every time. This can work around the limitations of higher-order verification. I propose that when requested using a new annotation @transparent on the inline function:
inline function should not be verified in isolation
the inlined body should not insert assume statements, so that any assertions in it are verified on each use
Here is another example of the use. This program verifies. Note that the inner function representing while loop is generated both for the inline function itself, and for its use:
inlinedefinitArray(a: Array[Int], v: Int):Unit=vari= a.length -1
(while i >0do
decreases(i)
a(i) = v
i -=1).invariant(0<= i && i < a.length)
deff=vala=newArray[Int](100)
initArray(a, 42)
trees:
@derived(f)
deffWhile(i: Int, a: Array[Int]): (Unit, Int, Array[Int]) = {
require((0<= i && i < a.length) &&& (i >0))
decreases(i)
vala:Array[Int] = a
vali:Int= i
valix:Int= i
vala:Array[Int] = {
assert(ix >=0&& ix < a.length, "Array index out of range")
a.updated(ix, 42)
}
valtmp:Unit= ()
vala:Array[Int] = a
valtmp:Unit= ()
valtmp:Unit= ()
vali:Int= i -1valtmp:Unit= ()
if (i >0) {
fWhile(i, a)
} else {
((), i, a)
}
}.ensuring {
(_res: (Unit, Int, Array[Int])) => {
vala:Array[Int] = _res._3
vali:Int= _res._2
(0<= i && i < a.length) &&&!(i >0)
}
}
definitArray(a: Array[Int], v: Int): (Unit, Array[Int]) = {
vala:Array[Int] = a
vali:Int= a.length -1valt: (Unit, Int, Array[Int]) =if (i >0) {
initArrayWhile(v, i, a)
} else {
((), i, a)
}
valres:Unit= t._1
vala:Array[Int] = t._3
vali:Int= t._2
(res, a)
}
@derived(initArray)
definitArrayWhile(v: Int, i: Int, a: Array[Int]): (Unit, Int, Array[Int]) = {
require((0<= i && i < a.length) &&& (i >0))
decreases(i)
vala:Array[Int] = a
vali:Int= i
valix:Int= i
vala:Array[Int] = {
assert(ix >=0&& ix < a.length, "Array index out of range")
a.updated(ix, v)
}
valtmp:Unit= ()
valtmp:Unit= ()
vali:Int= i -1valtmp:Unit= ()
if (i >0) {
initArrayWhile(v, i, a)
} else {
((), i, a)
}
}.ensuring {
(_res: (Unit, Int, Array[Int])) => {
vala:Array[Int] = _res._3
vali:Int= _res._2
(0<= i && i < a.length) &&&!(i >0)
}
}
deff:Unit= {
vala:Array[Int] = {
assert(100>=0, "Non-negative array size")
Array(0, ..., 0) (of size 100)
}
vali:Int= a.length -1valt: (Unit, Int, Array[Int]) =if (i >0) {
fWhile(i, a)
} else {
((), i, a)
}
valres:Unit= t._1
vala:Array[Int] = t._3
vali:Int= t._2
res
}
The text was updated successfully, but these errors were encountered:
Currently, inline defs are kept and verified like normal functions and their use appers verified a bit as if annotated by
@inlineOnce
. However, it would be relatively simple and useful to give users other options.inline directs scalac to make the call non-modular. This is orthogonal to whether the verification should be modular, which we control using annotations such as
@opaque
,@inline
,@inlineOnce
, see annotations at https://github.com/epfl-lara/stainless/blob/main/frontends/library/stainless/annotation/annotations.scalaCurrently, we inline such methods before vcgen, turning
require
intoassert
andensuring
intoassume
.Given:
invoking
gives
Adding
@opaque
tog
results inHowever, it seems useful for orthogonality of verification to treat
g
as opaque, so it would be good todef
was notinline
In the other direction, there is an opportunity to treat inline functions as transparent, as receipies for code and verification that should be applied every time. This can work around the limitations of higher-order verification. I propose that when requested using a new annotation
@transparent
on theinline
function:Here is another example of the use. This program verifies. Note that the inner function representing while loop is generated both for the inline function itself, and for its use:
trees:
The text was updated successfully, but these errors were encountered: