Skip to content
Snippets Groups Projects
Commit 745f8fdb authored by Manos Koukoutos's avatar Manos Koukoutos
Browse files

SMTLIBZ3Target

parent 8145b1c2
Branches
Tags
No related merge requests found
/* Copyright 2009-2016 EPFL, Lausanne */ /* Copyright 2009-2016 EPFL, Lausanne */
package leon package inox
package solvers package solvers
package smtlib package smtlib
import purescala.Common._
import purescala.Expressions._
import purescala.Constructors._
import purescala.Types._
import _root_.smtlib.common._ import _root_.smtlib.common._
import _root_.smtlib.parser.Terms.{Identifier => SMTIdentifier, Let => SMTLet, _} import _root_.smtlib.parser.Terms.{Identifier => SMTIdentifier, Let => SMTLet, _}
import _root_.smtlib.parser.Commands.{FunDef => SMTFunDef, _} import _root_.smtlib.parser.Commands.{FunDef => SMTFunDef, _}
...@@ -18,18 +13,22 @@ import _root_.smtlib.theories._ ...@@ -18,18 +13,22 @@ import _root_.smtlib.theories._
trait SMTLIBZ3Target extends SMTLIBTarget { trait SMTLIBZ3Target extends SMTLIBTarget {
import program._
import trees._
import symbols._
def targetName = "z3" def targetName = "z3"
def interpreterOps(ctx: LeonContext) = { def interpreterOps(ctx: InoxContext) = {
Seq( Seq(
"-in", "-in",
"-smt2" "-smt2"
) )
} }
def getNewInterpreter(ctx: LeonContext) = { def getNewInterpreter(ctx: InoxContext) = {
val opts = interpreterOps(ctx) val opts = interpreterOps(ctx)
context.reporter.debug("Invoking solver "+targetName+" with "+opts.mkString(" ")) ctx.reporter.debug("Invoking solver "+targetName+" with "+opts.mkString(" "))
new Z3Interpreter("z3", opts.toArray) new Z3Interpreter("z3", opts.toArray)
} }
...@@ -38,7 +37,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget { ...@@ -38,7 +37,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
protected var setSort: Option[SSymbol] = None protected var setSort: Option[SSymbol] = None
override protected def declareSort(t: TypeTree): Sort = { override protected def declareSort(t: Type): Sort = {
val tpe = normalizeType(t) val tpe = normalizeType(t)
sorts.cachedB(tpe) { sorts.cachedB(tpe) {
tpe match { tpe match {
...@@ -46,14 +45,14 @@ trait SMTLIBZ3Target extends SMTLIBTarget { ...@@ -46,14 +45,14 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
super.declareSort(BooleanType) super.declareSort(BooleanType)
declareSetSort(base) declareSetSort(base)
case BagType(base) => case BagType(base) =>
declareSort(RawArrayType(base, IntegerType)) declareSort(MapType(base, IntegerType))
case _ => case _ =>
super.declareSort(t) super.declareSort(t)
} }
} }
} }
protected def declareSetSort(of: TypeTree): Sort = { protected def declareSetSort(of: Type): Sort = {
setSort match { setSort match {
case None => case None =>
val s = SSymbol("Set") val s = SSymbol("Set")
...@@ -72,15 +71,28 @@ trait SMTLIBZ3Target extends SMTLIBTarget { ...@@ -72,15 +71,28 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
Sort(SMTIdentifier(setSort.get), Seq(declareSort(of))) Sort(SMTIdentifier(setSort.get), Seq(declareSort(of)))
} }
override protected def fromSMT(t: Term, otpe: Option[TypeTree] = None) override protected def fromSMT(t: Term, otpe: Option[Type] = None)
(implicit lets: Map[SSymbol, Term], letDefs: Map[SSymbol, DefineFun]): Expr = { (implicit lets: Map[SSymbol, Term], letDefs: Map[SSymbol, DefineFun]): Expr = {
(t, otpe) match { (t, otpe) match {
case (QualifiedIdentifier(ExtendedIdentifier(SSymbol("as-array"), k: SSymbol), _), Some(tpe)) => case (QualifiedIdentifier(ExtendedIdentifier(SSymbol("as-array"), k: SSymbol), _), Some(tpe)) =>
if (letDefs contains k) { if (letDefs contains k) {
val MapType(keyType, valueType) = tpe
val DefineFun(SMTFunDef(a, Seq(SortedVar(arg, akind)), rkind, body)) = letDefs(k)
def extractCases(e: Term): (Map[Expr, Expr], Expr) = e match {
case ITE(SMTEquals(SimpleSymbol(`arg`), k), v, e) =>
val (cs, d) = extractCases(e)
(Map(fromSMT(k, keyType) -> fromSMT(v, valueType)) ++ cs, d)
case e =>
(Map(),fromSMT(e, valueType))
}
// Need to recover value form function model // Need to recover value form function model
fromRawArray(extractRawArray(letDefs(k), tpe), tpe) val (cases, default) = extractCases(body)
FiniteMap(cases.toSeq, default, keyType)
} else { } else {
throw LeonFatalError("Array on non-function or unknown symbol "+k) throw FatalError("Array on non-function or unknown symbol "+k)
} }
case (FunctionApplication( case (FunctionApplication(
...@@ -89,8 +101,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget { ...@@ -89,8 +101,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
), Some(tpe)) => ), Some(tpe)) =>
val ktpe = sorts.fromB(k) val ktpe = sorts.fromB(k)
val vtpe = sorts.fromB(v) val vtpe = sorts.fromB(v)
FiniteMap(Seq(), fromSMT(defV), ktpe)
fromRawArray(RawArrayValue(ktpe, Map(), fromSMT(defV, vtpe)), tpe)
case _ => case _ =>
super.fromSMT(t, otpe) super.fromSMT(t, otpe)
...@@ -103,11 +114,9 @@ trait SMTLIBZ3Target extends SMTLIBTarget { ...@@ -103,11 +114,9 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
* ===== Set operations ===== * ===== Set operations =====
*/ */
case fs @ FiniteSet(elems, base) => case fs @ FiniteSet(elems, base) =>
declareSort(fs.getType) val st @ SetType(base) = fs.getType
declareSort(st)
toSMT(RawArrayValue(base, elems.map { toSMT(FiniteMap(elems map ((_, BooleanLiteral(true))), BooleanLiteral(false), BooleanType))
case k => k -> BooleanLiteral(true)
}.toMap, BooleanLiteral(false)))
case SubsetOf(ss, s) => case SubsetOf(ss, s) =>
// a isSubset b ==> (a zip b).map(implies) == (* => true) // a isSubset b ==> (a zip b).map(implies) == (* => true)
...@@ -135,13 +144,13 @@ trait SMTLIBZ3Target extends SMTLIBTarget { ...@@ -135,13 +144,13 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
ArrayMap(SSymbol("and"), toSMT(l), toSMT(r)) ArrayMap(SSymbol("and"), toSMT(l), toSMT(r))
case fb @ FiniteBag(elems, base) => case fb @ FiniteBag(elems, base) =>
declareSort(fb.getType) val BagType(t) = fb.getType
declareSort(BagType(t))
toSMT(RawArrayValue(base, elems, InfiniteIntegerLiteral(0))) toSMT(FiniteMap(elems, IntegerLiteral(0), t))
case BagAdd(b, e) => case BagAdd(b, e) =>
val bid = FreshIdentifier("b", b.getType, true) val bid = FreshIdentifier("b", true)
val eid = FreshIdentifier("e", e.getType, true) val eid = FreshIdentifier("e", true)
val (bSym, eSym) = (id2sym(bid), id2sym(eid)) val (bSym, eSym) = (id2sym(bid), id2sym(eid))
SMTLet(VarBinding(bSym, toSMT(b)), Seq(VarBinding(eSym, toSMT(e))), ArraysEx.Store(bSym, eSym, SMTLet(VarBinding(bSym, toSMT(b)), Seq(VarBinding(eSym, toSMT(e))), ArraysEx.Store(bSym, eSym,
Ints.Add(ArraysEx.Select(bSym, eSym), Ints.NumeralLit(1)))) Ints.Add(ArraysEx.Select(bSym, eSym), Ints.NumeralLit(1))))
...@@ -162,7 +171,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget { ...@@ -162,7 +171,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
val minus = SortedSymbol("-", List(IntegerType, IntegerType).map(declareSort), declareSort(IntegerType)) val minus = SortedSymbol("-", List(IntegerType, IntegerType).map(declareSort), declareSort(IntegerType))
val div = SortedSymbol("/", List(IntegerType, IntegerType).map(declareSort), declareSort(IntegerType)) val div = SortedSymbol("/", List(IntegerType, IntegerType).map(declareSort), declareSort(IntegerType))
val did = FreshIdentifier("d", b1.getType, true) val did = FreshIdentifier("d", true)
val dSym = id2sym(did) val dSym = id2sym(did)
val all2 = ArrayConst(declareSort(IntegerType), Ints.NumeralLit(2)) val all2 = ArrayConst(declareSort(IntegerType), Ints.NumeralLit(2))
...@@ -174,33 +183,6 @@ trait SMTLIBZ3Target extends SMTLIBTarget { ...@@ -174,33 +183,6 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
super.toSMT(e) super.toSMT(e)
} }
protected def extractRawArray(s: DefineFun, tpe: TypeTree)(implicit lets: Map[SSymbol, Term], letDefs: Map[SSymbol, DefineFun]): RawArrayValue = s match {
case DefineFun(SMTFunDef(a, Seq(SortedVar(arg, akind)), rkind, body)) =>
val (argTpe, retTpe) = tpe match {
case SetType(base) => (base, BooleanType)
case MapType(from, to) => (from, library.optionType(to))
case ArrayType(base) => (Int32Type, base)
case FunctionType(args, ret) => (tupleTypeWrap(args), ret)
case RawArrayType(from, to) => (from, to)
case _ => unsupported(tpe, "Unsupported type for (un)packing into raw arrays (got kinds "+akind+" -> "+rkind+")")
}
def extractCases(e: Term): (Map[Expr, Expr], Expr) = e match {
case ITE(SMTEquals(SimpleSymbol(`arg`), k), v, e) =>
val (cs, d) = extractCases(e)
(Map(fromSMT(k, argTpe) -> fromSMT(v, retTpe)) ++ cs, d)
case e =>
(Map(),fromSMT(e, retTpe))
}
val (cases, default) = extractCases(body)
RawArrayValue(argTpe, cases, default)
case _ =>
throw LeonFatalError("Unable to extract "+s)
}
protected object SortedSymbol { protected object SortedSymbol {
def apply(op: String, from: List[Sort], to: Sort) = { def apply(op: String, from: List[Sort], to: Sort) = {
def simpleSort(s: Sort): Boolean = s.subSorts.isEmpty && !s.id.isIndexed def simpleSort(s: Sort): Boolean = s.subSorts.isEmpty && !s.id.isIndexed
...@@ -212,7 +194,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget { ...@@ -212,7 +194,7 @@ trait SMTLIBZ3Target extends SMTLIBTarget {
protected object ArrayMap { protected object ArrayMap {
def apply(op: SExpr, arrs: Term*) = { def apply(op: SExpr, arrs: Term*) = {
FunctionApplication( FunctionApplication(
QualifiedIdentifier(SMTIdentifier(SSymbol("map"), List(op))), QualifiedIdentifier(SMTIdentifier(SSymbol("map"), List(op)), None),
arrs arrs
) )
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment