1 / 16

Scala Z3 Integrating SMT and Programming

Scala Z3 Integrating SMT and Programming. Ali Sinan Köksal , Viktor Kuncak , Philippe Suter. École Polytechnique Fédérale de Lausanne. “Scalable programming language”. Blending of functional and object-oriented programming Runs on the Java Virtual Machine (and .NET)

osric
Télécharger la présentation

Scala Z3 Integrating SMT and Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ScalaZ3Integrating SMT and Programming Ali SinanKöksal, Viktor Kuncak, Philippe Suter ÉcolePolytechniqueFédérale de Lausanne

  2. “Scalable programming language” 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) 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

  3. ~$ ./demo

  4. C and Scala side-by-side import z3.scala._…valcfg = newZ3Configcfg.setParamValue("MODEL", "true")valz3 = newZ3Context(cfg)valintSort : Z3Sort = z3.mkIntSortvalf : Z3FuncDecl = z3.mkFuncDecl(  z3.mkStringSymbol("f"),  List(intSort), intSort)valx : Z3AST = z3.mkConst(  z3.mkStringSymbol("x"), intSort)valy : Z3AST = z3.mkConst(  z3.mkStringSymbol("y"), intSort)valineq : Z3AST = z3.mkNot(z3.mkEq(x, z3.mkApp(f, y)))z3.assertCnstr(ineq)z3.checkAndGetModel match {case (Some(true), m) ⇒ println(m)case _ ⇒ ;} #include "z3.h"… Z3_configcfg = Z3_mk_config();Z3_set_param_value(cfg, "MODEL", "true");Z3_contextz3 = Z3_mk_context(cfg);Z3_sortintSort = Z3_mk_int_sort(z3);Z3_func_declf = Z3_mk_func_decl(z3,Z3_mk_string_symbol(z3,"f"),1, &intSort, intSort);Z3_astx = Z3_mk_const(z3,Z3_mk_string_symbol(z3,"x"), intSort);Z3_asty = Z3_mk_const(z3, Z3_mk_string_symbol(z3,"y"), intSort);Z3_astineq = 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)); }

  5. def choose[A,B](p: (Val[A],Val[B])⇒Tree[BoolSort]) : (A,B) deffind[A,B](p: (Val[A],Val[B])⇒Tree[BoolSort]) : Option[(A,B)] deffindAll[A,B](p: (Val[A],Val[B])⇒Tree[BoolSort]): Iterator[(A,B)]

  6. Anatomy of an Inline Invocation import z3.scala._ importdsl._...choose((y: Val[Int⇒Int], x: Val[Int], y: Val[Int]) ⇒ !(x === f(y))) imports and Val[_]s only manifestations of the library Desired return types (actual Scala types). Domain specific language of formulas resembles Scala expressions. Returned values are Scala values (including functions).

  7. for Comprehensions Can you find positive x, y, z such that 2x + 3y≤ 40, xz = 3y2, and y is prime? 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) Returned expression. Generators: sequences, computed eagerly or lazily. Filter: arbitrary boolean expression. (1,2,12), (1,3,27), (1,5,75), (1,7,147), (1,11,363), (3,11,121), (3,5,25), (3,7,49)

  8. Implementation Aspects

  9. Basic representation: class Z3AST(ptr : Long) • Automatic conversions between the two kinds. • Soft typing for the DSL Trees. Tree hierarchy as part of the DSL: abstractclass Tree[+T >: Bottom <: Top] { ... def <(other : Tree[_ <: IntSort]) : Tree[BoolSort] = ... ... } implicit defast2Tree(ast : Z3AST) : Tree[Bottom] implicit deftree2AST(tree : Tree[_]) : Z3AST Top IntSort BoolSort … SetSort Bottom

  10. DSL in Action import z3.scala._…valcfg = newZ3Configcfg.setParamValue("MODEL", "true")valz3 = newZ3Context(cfg)valintSort : Z3Sort = z3.mkIntSortvalf : Z3FuncDecl = z3.mkFuncDecl(  z3.mkStringSymbol("f"),  List(intSort), intSort)valx : Z3AST = z3.mkConst(  z3.mkStringSymbol("x"), intSort)valy : Z3AST = z3.mkConst(  z3.mkStringSymbol("y"), intSort)valineq : Z3AST = z3.mkNot(z3.mkEq(x, z3.mkApp(f, y))) import z3.scala._…val z3 = newZ3Context("MODEL“ -> true)valintSort= z3.mkIntSortvalf = z3.mkFuncDecl("f", intSort, intSort) valx = z3.mkConst("x", intSort)valy = z3.mkConst("y", intSort) valineq : Z3AST = !(x === f(y))

  11. Z3 Sorts Scala Types Array[A,B] Int Boolean Int BV[32] Set[A] A⇒B Bool … … • Different function calls to create constants and to retrieve the models: • Users should be able to ignore the underlying representation: m.evalAs[Boolean](tree) m.evalAs[Int](tree) m.evalAs[Int⇒Int](tree) ctx.getBool(m.eval(tree)) ctx.getNumeralInt(m.eval(tree)) m.getArrayValue(tree)...

  12. defevalAs[T](tree : Z3AST) : T defevalAs[T : Evaluator](tree : Z3AST) : T defevalAs[T](tree : Z3AST)(implicit e : Evaluator[T]) : T @implicitNotFound(“No known model evaluator for type ${T}.”) trait Evaluator[T] { defeval(model : Z3Model, tree : Z3AST) : T } implicit object IntEvaluatorextends Evaluator[Int] { defeval(model : Z3Model, tree : Z3AST) : Int= ... } implicit deflift2Set[T : Evaluator] = newEvaluator[Set[T]] { defeval(model : Z3Model, tree : Z3AST) : Set[T] = ... } m.evalAs[Int](t) m.evalAs[Int](t)(IntEvaluator) m.evalAs[Set[Set[Int]]](t) m.evalAs[...](t)(lift2Set(lift2Set(IntEvaluator)))

  13. Procedural Attachments val z3 = new Z3Context(“MODEL” -> true) valstringTheory= new ProceduralAttachment[String](z3) { valconcat = function((s1,s2) ⇒ s1 + s2) valsubstr = predicate((s1,s2) ⇒ s2.contains(s1)) valevenLength= predicate(_.length % 2 == 0) } importstringTheory._ 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)

  14. Applications MUNCH: Decision procedure for multisets and sets R. Piskac, V. Kuncak, IJCAR 2010 Z3 extension for sets with cardinality constraints P. Suter, R. Steiger, V. Kuncak, VMCAI 2011 Leon: Verifier for functional programs P. Suter, A.S. Köksal, V. Kuncak, SAS 2011, http://lara.epfl.ch/leon/ Kaplan: Constraint programming in Scala Ali SinanKöksal’s Master Thesis Other users at ETH Zürich, KU Leuven

  15. Availability http://lara.epfl.ch/w/ScalaZ3 https://github.com/psuter/ScalaZ3 (Tested on Windows and Linux, on 32 and 64 bit architectures.)

  16. Thank you.

More Related