From a454d391ef27051df6aa835479103bd174a3b47b Mon Sep 17 00:00:00 2001
From: Manos Koukoutos <emmanouil.koukoutos@epfl.ch>
Date: Tue, 28 Apr 2015 09:53:43 +0200
Subject: [PATCH] Fix some bugs in new z3 solver

---
 .../smtlib/SMTLIBZ3QuantifiedTarget.scala     | 98 +++++++++----------
 1 file changed, 49 insertions(+), 49 deletions(-)

diff --git a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedTarget.scala b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedTarget.scala
index ab38c5203..3087d1183 100644
--- a/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedTarget.scala
+++ b/src/main/scala/leon/solvers/smtlib/SMTLIBZ3QuantifiedTarget.scala
@@ -3,9 +3,10 @@ package leon.solvers.smtlib
 import leon.purescala.DefOps._
 import leon.purescala.Definitions.TypedFunDef
 import leon.purescala.ExprOps._
-import leon.purescala.Expressions.{Equals, FunctionInvocation}
+import leon.purescala.Expressions._
+import leon.purescala.Constructors._
 import smtlib.parser.Commands.{DeclareFun, Assert}
-import smtlib.parser.Terms.{Term, SortedVar, SSymbol, ForAll}
+import smtlib.parser.Terms.{ForAll => SMTForall, SSymbol}
 
 /**
  * This solver models function definitions as universally quantified formulas.
@@ -20,57 +21,56 @@ trait SMTLIBZ3QuantifiedTarget extends SMTLIBZ3Target {
   override def targetName = "z3-quantified"
 
   override def declareFunction(tfd: TypedFunDef): SSymbol = {
-    if (tfd.params.isEmpty) {
-      super[SMTLIBZ3Target].declareFunction(tfd)
-    } else {
-      val (funs, exploredAll) = typedTransitiveCallees(Set(tfd), Some(typedFunDefExplorationLimit))
-      if (!exploredAll) {
-        reporter.warning(
-          s"Did not manage to explore the space of typed functions called from ${tfd.id}. The solver may fail"
-        )
-      }
 
-      val smtFunDecls = funs.toSeq.collect {
-        case tfd if !functions.containsA(tfd) && tfd.params.nonEmpty =>
-          val id = if (tfd.tps.isEmpty) {
-            tfd.id
-          } else {
-            tfd.id.freshen
-          }
-          val sym = id2sym(id)
-          functions +=(tfd, sym)
-          sendCommand(DeclareFun(
-            sym,
-            tfd.params map { p => declareSort(p.getType) },
-            declareSort(tfd.returnType)
-          ))
-          sym
-      }
-      smtFunDecls foreach { sym =>
-        val tfd = functions.toA(sym)
-        val sortedVars = tfd.params.map { p =>
-          SortedVar(id2sym(p.id), declareSort(p.getType))
-        }
-        val term =
-          if (sortedVars.isEmpty) {
-            toSMT(Equals(FunctionInvocation(tfd, Seq()), tfd.body.get))(Map())
-          } else {
-            ForAll(
-              sortedVars.head,
-              sortedVars.tail,
-              toSMT(Equals(
-                FunctionInvocation(tfd, tfd.params.map {_.toVariable}),
-                matchToIfThenElse(tfd.body.get)
-              ))(
-                tfd.params.map { p => (p.id, id2sym(p.id): Term) }.toMap
-              )
-            )
+    val (funs, exploredAll) = typedTransitiveCallees(Set(tfd), Some(typedFunDefExplorationLimit))
+    if (!exploredAll) {
+      reporter.warning(
+        s"Did not manage to explore the space of typed functions called from ${tfd.id}. The solver may fail"
+      )
+    }
+
+    val smtFunDecls = funs.toSeq.collect {
+      case tfd if !functions.containsA(tfd) =>
+        val id = if (tfd.tps.isEmpty) {
+          tfd.id
+        } else {
+          tfd.id.freshen
         }
-        sendCommand(Assert(term))
-      }
+        val sym = id2sym(id)
+        functions +=(tfd, sym)
+        sendCommand(DeclareFun(
+          sym,
+          tfd.params map { p => declareSort(p.getType) },
+          declareSort(tfd.returnType)
+        ))
+        sym
+    }
+    smtFunDecls foreach { sym =>
+      val tfd = functions.toA(sym)
+      val term = quantifiedTerm(
+        SMTForall,
+        tfd.params map { _.id },
+        matchToIfThenElse(Equals(
+          FunctionInvocation(tfd, tfd.params.map {_.toVariable}),
+          matchToIfThenElse(tfd.body.get)
+        ))
+      )
+      sendCommand(Assert(term))
 
-      functions.toB(tfd)
+      tfd.postcondition foreach { post =>
+        val axiom = matchToIfThenElse(implies(
+          tfd.precondition getOrElse BooleanLiteral(true),
+          application(
+            post,
+            Seq(FunctionInvocation(tfd, tfd.params map { _.toVariable }))
+          )
+        ))
+        sendCommand(Assert(quantifiedTerm(SMTForall, axiom)))
+      }
     }
+
+    functions.toB(tfd)
   }
 
+
 }
-- 
GitLab