Estamos teniendo problemas de rendimiento con lo que creo que es la parte de Z3 que trata la aritmética no lineal. Aquí hay un ejemplo concreto de Boogie, que cuando se verifica con Z3 (versión 4.1) tarda mucho tiempo (del orden de 3 minutos) en completarse.Rendimiento Z3 con aritmética no lineal
const D: int;
function f(n: int) returns (int) { n * D }
procedure test() returns()
{
var a, b, c: int;
var M: [int]int;
var t: int;
assume 0 < a && 1000 * a < f(1);
assume 0 < c && 1000 * c < f(1);
assume f(100) * b == a * c;
assert M[t] > 0;
}
Parece que el problema está causado por una interacción de las funciones, la asunción gama de variables enteras así como multiplicaciones de valores (desconocido) enteros. La afirmación al final no debe ser comprobable. En lugar de fallar rápidamente, parece que Z3 tiene formas de instanciar muchos términos de alguna manera, ya que sus consumos de memoria crecen bastante rápido a unos 300 MB, momento en el que se da por vencido.
Me pregunto si esto es un error, o si es posible mejorar la heurística en cuando Z3 debería detener la búsqueda en la dirección particular en la que actualmente está tratando de resolver el problema.
Una cosa interesante es que la función inline utilizando
function {:inline} f(n: int) returns (int) { n * D }
realiza la verificación terminar muy rápidamente.
Antecedentes: Este es un caso de prueba mínimo para un problema que vemos en nuestro verificador Chalice. Allí, los programas de Boogie son mucho más largos, potencialmente con múltiples suposiciones de un tipo similar. A menudo, la verificación no parece terminar en absoluto.
¿Alguna idea?
¿Podría incluir/publicar el archivo Z3? –
Claro. Utilicé la opción/proverLog de Boogie para obtener la entrada Z3 [sin alinear la función] (http://pastebin.com/6HjT9DmC) y [con inline] (http://pastebin.com/91kxxQrC). – stefan