16
Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

Embed Size (px)

Citation preview

Page 1: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

ScalaZ3 Integrating SMT and Programming

Ali Sinan Köksal, Viktor Kuncak, Philippe SuterÉcole Polytechnique Fédérale de Lausanne

Page 2: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

• Efficient SMT solver from Microsoft Research• Supports many theories through DPLL(T) and Nelson-

Oppen combination• SMT-LIB standard input format, as well as C, .NET, OCaml,

and Python bindings

• Blending of functional and object-oriented programming• Runs on the Java Virtual Machine (and .NET)

• Rich type system (generics, type classes, implicit conversions, etc.)

• Now used by over 100’000 developers (incl. Twitter, UBS, LinkedIn)

“Scalable programming language”

Page 3: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

~$ ./demo

Page 4: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

#include "z3.h"…Z3_config cfg = Z3_mk_config();Z3_set_param_value(cfg, "MODEL", "true");Z3_context z3 = Z3_mk_context(cfg);

Z3_sort intSort = Z3_mk_int_sort(z3);

Z3_func_decl f = Z3_mk_func_decl(z3,  Z3_mk_string_symbol(z3,"f"),  1, &intSort, intSort);Z3_ast x = Z3_mk_const(z3,  Z3_mk_string_symbol(z3,"x"), intSort);Z3_ast y = Z3_mk_const(z3, Z3_mk_string_symbol(z3,"y"), intSort);

Z3_ast ineq = Z3_mk_not(z3,  Z3_mk_eq(z3, x, Z3_mk_app(z3, f, 1, &y)));

Z3_assert_cnstr(z3, ineq);

Z3_model m;if(Z3_check_and_get_model(z3, &m)) { printf("%s", Z3_model_to_string(z3, m));}

import z3.scala._…val cfg = new Z3Configcfg.setParamValue("MODEL", "true")val z3 = new Z3Context(cfg)

val intSort : Z3Sort = z3.mkIntSort

val f : Z3FuncDecl = z3.mkFuncDecl(  z3.mkStringSymbol("f"),  List(intSort), intSort)val x : Z3AST = z3.mkConst(  z3.mkStringSymbol("x"), intSort)val y : Z3AST = z3.mkConst(  z3.mkStringSymbol("y"), intSort)

val ineq : Z3AST = z3.mkNot(  z3.mkEq(x, z3.mkApp(f, y)))

z3.assertCnstr(ineq)

z3.checkAndGetModel match {  case (Some(true), m) ⇒ println(m)  case _ ⇒ ;}

C and Scala side-by-side

Page 5: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

def choose[A,B](p: (Val[A],Val[B])⇒Tree[BoolSort]) : (A,B)

def find[A,B](p: (Val[A],Val[B])⇒Tree[BoolSort]) : Option[(A,B)]

def findAll[A,B](p: (Val[A],Val[B])⇒Tree[BoolSort]) : Iterator[(A,B)]

Page 6: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

Anatomy of an Inline Invocation

import z3.scala._import dsl._...choose((y: Val[Int⇒Int], x: Val[Int], y: Val[Int]) ⇒ !(x === f(y)))

Desired return types (actual Scala types).

Domain specific language of formulas resembles

Scala expressions.

Returned values are Scala values (including functions).

imports and Val[_]s only manifestations of

the library

Page 7: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

for Comprehensions

for((x,y) ← findAll((x: Val[Int], y: Val[Int]) ⇒ x > 0 && y > x && x * 2 + y * 3 <= 40); if(isPrime(y));  z ← findAll((z: Val[Int]) ⇒ z * x === 3 * y * y))    yield (x, y, z)

Can you find positive x, y, z such that 2x + 3y ≤ 40, xz = 3y2, and y is prime?

(1,2,12), (1,3,27), (1,5,75), (1,7,147), (1,11,363), (3,11,121), (3,5,25), (3,7,49)

Returned expression.

Filter: arbitrary boolean expression.

Generators: sequences, computed eagerly or lazily.

Page 8: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

Implementation Aspects

Page 9: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

class Z3AST(ptr : Long)

abstract class Tree[+T >: Bottom <: Top] { ... def <(other : Tree[_ <: IntSort]) : Tree[BoolSort] = ... ...}

Bottom

Top

IntSort BoolSort … SetSort

implicit def ast2Tree(ast : Z3AST) : Tree[Bottom]implicit def tree2AST(tree : Tree[_]) : Z3AST

• Automatic conversions between the two kinds.• Soft typing for the DSL Trees.

Basic representation:

Tree hierarchy as part of the DSL:

Page 10: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

import z3.scala._…val cfg = new Z3Configcfg.setParamValue("MODEL", "true")val z3 = new Z3Context(cfg)

val intSort : Z3Sort = z3.mkIntSort

val f : Z3FuncDecl = z3.mkFuncDecl(  z3.mkStringSymbol("f"),  List(intSort), intSort)val x : Z3AST = z3.mkConst(  z3.mkStringSymbol("x"), intSort)val y : Z3AST = z3.mkConst(  z3.mkStringSymbol("y"), intSort)

val ineq : Z3AST = z3.mkNot(  z3.mkEq(x, z3.mkApp(f, y)))

DSL in Action

import z3.scala._…val z3 = new Z3Context("MODEL“ -> true)

val intSort = z3.mkIntSort

val f = z3.mkFuncDecl(  "f", intSort, intSort)

val x = z3.mkConst("x", intSort)

val y = z3.mkConst("y", intSort)

val ineq : Z3AST = !(x === f(y))

Page 11: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

Z3 Sorts

Int BV[32]

Bool

Array[A,B]

Scala Types

Int Boolean

Set[A]A⇒B

• Users should be able to ignore the underlying representation:

• Different function calls to create constants and to retrieve the models:

ctx.getBool(m.eval(tree))ctx.getNumeralInt(m.eval(tree))m.getArrayValue(tree)...

m.evalAs[Boolean](tree)m.evalAs[Int](tree)m.evalAs[Int⇒Int](tree)

Page 12: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

def evalAs[T](tree : Z3AST) : T

trait Evaluator[T] { def eval(model : Z3Model, tree : Z3AST) : T}

implicit object IntEvaluator extends Evaluator[Int] { def eval(model : Z3Model, tree : Z3AST) : Int = ...}

m.evalAs[Int](t) m.evalAs[Int](t)(IntEvaluator)

implicit def lift2Set[T : Evaluator] = new Evaluator[Set[T]] { def eval(model : Z3Model, tree : Z3AST) : Set[T] = ...}

m.evalAs[Set[Set[Int]]](t)

m.evalAs[...](t)(lift2Set(lift2Set(IntEvaluator)))

def evalAs[T : Evaluator](tree : Z3AST) : T

def evalAs[T](tree : Z3AST)(implicit e : Evaluator[T]) : T

@implicitNotFound(“No known model evaluator for type ${T}.”)

Page 13: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

Procedural Attachments

import stringTheory._

val s = z3.mkConst(“s”, stringTheory.sort)

z3.assertCnstr(s === “world” || s === “moon”)z3.assertCnstr(evenLength(s))z3.check

> Some(true)

z3.assertCnstr(substr(concat(“hello”, s), “low”))z3.check

> Some(false)

val z3 = new Z3Context(“MODEL” -> true)val stringTheory = new ProceduralAttachment[String](z3) { val concat = function((s1,s2) ⇒ s1 + s2)  val substr = predicate((s1,s2) ⇒ s2.contains(s1))  val evenLength = predicate(_.length % 2 == 0)}

Page 14: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

Applications

Z3 extension for sets with cardinality constraintsP. Suter, R. Steiger, V. Kuncak, VMCAI 2011

MUNCH: Decision procedure for multisets and setsR. Piskac, V. Kuncak, IJCAR 2010

Leon: Verifier for functional programsP. Suter, A.S. Köksal, V. Kuncak, SAS 2011, http://lara.epfl.ch/leon/

Other users at ETH Zürich, KU Leuven

Kaplan: Constraint programming in ScalaAli Sinan Köksal’s Master Thesis

Page 15: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

https://github.com/psuter/ScalaZ3

Availability

http://lara.epfl.ch/w/ScalaZ3

(Tested on Windows and Linux, on 32 and 64 bit architectures.)

Page 16: Scala Z3 Integrating SMT and Programming Ali Sinan Köksal, Viktor Kuncak, Philippe Suter École Polytechnique Fédérale de Lausanne

Thank you.