diff --git a/lib/z3.jar b/lib/z3.jar
deleted file mode 100644
index 2fd797b68a3ae3d5a17bad12f77b857b7e2b4ef3..0000000000000000000000000000000000000000
Binary files a/lib/z3.jar and /dev/null differ
diff --git a/s-f b/s-f
index 0e04980aa1736203249654a48f26a1ca5dd54a08..5ac3f3d27a2b992290944f8cb26b752568384507 100755
--- a/s-f
+++ b/s-f
@@ -3,4 +3,4 @@ SCALALIBDIR=/home/psuter/scala/current/lib
 DISTDIR=/home/psuter/guru-svn/funcheck/dist
 LIBDIR=/home/psuter/guru-svn/funcheck/lib
 SCALAHOME=/home/psuter/scala/current
-java -Dscala.home=${SCALAHOME} -classpath ${SCALALIBDIR}/scala-compiler.jar:${SCALALIBDIR}/scala-library.jar:${DISTDIR}/funcheck-plugin.jar:${LIBDIR}/z3.jar scala.tools.nsc.Main -Xplugin:${DISTDIR}/funcheck-plugin.jar $@
+LD_LIBRARY_PATH=/home/psuter/software/z3/lib java -Dscala.home=${SCALAHOME} -classpath ${SCALALIBDIR}/scala-compiler.jar:${SCALALIBDIR}/scala-library.jar:${DISTDIR}/funcheck-plugin.jar:${LIBDIR}/z3.jar scala.tools.nsc.Main -Xplugin:${DISTDIR}/funcheck-plugin.jar $@
diff --git a/src/purescala/Analysis.scala b/src/purescala/Analysis.scala
index f01145dae44bf5317dfdb24210130dd78f7a387e..220d46a057206db75b5ec992b3b5ded5ff86839d 100644
--- a/src/purescala/Analysis.scala
+++ b/src/purescala/Analysis.scala
@@ -17,18 +17,26 @@ object Analysis {
     //  - all global invariants are satisfied 
     def analyze(program: Program) : Unit = {
         val z3cfg = new Z3Config()
-        //z3cfg.setParamValue("MODEL", "TRUE")
+        z3cfg.setParamValue("MODEL", "true")
         val z3 = new Z3Context(z3cfg)
 
         program.mainObject.defs.filter(_.isInstanceOf[FunDef]).foreach(df => {
             val funDef = df.asInstanceOf[FunDef]
             val vc = postconditionVC(funDef)
             if(vc != BooleanLiteral(true)) {
-                println("Verification condition for " + funDef.id + ":")
+                println("Verification condition (post) for " + funDef.id + ":")
                 println(vc)
                 val (z3f,stupidMap) = toZ3Formula(z3, vc)
                 z3.assertCnstr(z3.mkNot(z3f))
-                println("Valid? " + z3.check())
+                //z3.print
+                z3.checkAndGetModel() match {
+                    case (Some(true),m) => {
+                        println("There's a bug! Here's a model for a counter-example:")
+                        m.print
+                    }
+                    case (Some(false),_) => println("Contract satisfied!")
+                    case (None,_) => println("Z3 couldn't run properly or does not know the answer :(")
+                }
             }
         }) 
     }
@@ -40,7 +48,10 @@ object Analysis {
         if(post.isEmpty) {
             BooleanLiteral(true)
         } else {
-            replaceInExpr(Map(ResultVariable() -> functionDefinition.body), post.get)
+            if(prec.isEmpty)
+                replaceInExpr(Map(ResultVariable() -> functionDefinition.body), post.get)
+            else
+                Implies(prec.get, replaceInExpr(Map(ResultVariable() -> functionDefinition.body), post.get))
         }
     }
 
@@ -63,7 +74,21 @@ object Analysis {
             case And(exs) => And(exs.map(rec(_)))
             case Or(exs) => Or(exs.map(rec(_)))
             case Not(e) => Not(rec(e))
-            case BinaryOperator(t1,t2,recons) => recons(rec(t1),rec(t2))
+            case u @ UnaryOperator(t,recons) => {
+              val r = rec(t)
+              if(r != t)
+                recons(r).setType(u.getType)
+              else
+                u
+            }
+            case b @ BinaryOperator(t1,t2,recons) => {
+              val r1 = rec(t1)
+              val r2 = rec(t2)
+              if(r1 != t1 || r2 != t2)
+                recons(r1,r2).setType(b.getType)
+              else
+                b
+            }
             case _ => ex
         }
 
@@ -89,6 +114,7 @@ object Analysis {
             case Or(exs) => z3.mkOr(exs.map(rec(_)) : _*)
             case Not(Equals(l,r)) => z3.mkDistinct(rec(l),rec(r))
             case Not(e) => z3.mkNot(rec(e))
+            case Implies(l,r) => z3.mkImplies(rec(l), rec(r))
             case IntLiteral(v) => z3.mkInt(v, intSort)
             case BooleanLiteral(v) => if (v) z3.mkTrue() else z3.mkFalse()
             case Equals(l,r) => z3.mkEq(rec(l),rec(r))
diff --git a/src/purescala/PrettyPrinter.scala b/src/purescala/PrettyPrinter.scala
index c96723707f278ed8a0b0aec944a71a993231e7df..99a6074b5010b82d1b1f05e7c59b8c241fadb027 100644
--- a/src/purescala/PrettyPrinter.scala
+++ b/src/purescala/PrettyPrinter.scala
@@ -72,6 +72,7 @@ object PrettyPrinter {
     case Or(exprs) => ppNary(sb, exprs, " \u2228 ", lvl)             // \lor
     case Not(Equals(l, r)) => ppBinary(sb, l, r, " \u2260 ", lvl)    // \neq
     case Not(expr) => ppUnary(sb, expr, "\u00AC", lvl)               // \neg
+    case Implies(l,r) => ppBinary(sb, l, r, "==>", lvl)              
     case UMinus(expr) => ppUnary(sb, expr, "-", lvl)
     case Equals(l,r) => ppBinary(sb, l, r, " == ", lvl)
     case IntLiteral(v) => sb.append(v)
diff --git a/src/purescala/Trees.scala b/src/purescala/Trees.scala
index e6bbcaf74cda077edf521b91e7de37918e4a8105..8d617a834b0eab57a5a4e871d2468335dfccc447 100644
--- a/src/purescala/Trees.scala
+++ b/src/purescala/Trees.scala
@@ -54,6 +54,10 @@ object Trees {
         if(and == null) None else Some(and.exprs)
   }
 
+  class And(val exprs: Seq[Expr]) extends Expr with FixedType {
+    val fixedType = BooleanType
+  }
+
   object Or {
     def apply(exprs: Seq[Expr]) : Or = new Or(exprs)
 
@@ -68,12 +72,22 @@ object Trees {
         if(or == null) None else Some(or.exprs)
   }
 
-  class And(val exprs: Seq[Expr]) extends Expr
-  class Or(val exprs: Seq[Expr]) extends Expr
-  case class Not(expr: Expr) extends Expr 
+  class Or(val exprs: Seq[Expr]) extends Expr with FixedType {
+    val fixedType = BooleanType
+  }
+
+  case class Implies(left: Expr, right: Expr) extends Expr with FixedType {
+    val fixedType = BooleanType
+  }
+
+  case class Not(expr: Expr) extends Expr with FixedType {
+    val fixedType = BooleanType
+  }
 
   /* Maybe we should split this one depending on types? */
-  case class Equals(left: Expr, right: Expr) extends Expr  
+  case class Equals(left: Expr, right: Expr) extends Expr with FixedType {
+    val fixedType = BooleanType
+  }
   
   /* Literals */
   case class Variable(id: Identifier) extends Expr {
@@ -88,8 +102,12 @@ object Trees {
     val value: T
   }
 
-  case class IntLiteral(value: Int) extends Literal[Int] 
-  case class BooleanLiteral(value: Boolean) extends Literal[Boolean] 
+  case class IntLiteral(value: Int) extends Literal[Int] with FixedType {
+    val fixedType = Int32Type
+  }
+  case class BooleanLiteral(value: Boolean) extends Literal[Boolean] with FixedType {
+    val fixedType = BooleanType
+  }
   case class StringLiteral(value: String) extends Literal[String]
 
   case class CaseClass(classDef: CaseClassDef, args: Seq[Expr]) extends Expr
@@ -142,7 +160,7 @@ object Trees {
 
   case class MapGet(map: Expr, key: Expr) extends Expr 
   case class MapUnion(map1: Expr, map2: Expr) extends Expr 
-  case class MapDiffrence(map: Expr, keys: Expr) extends Expr 
+  case class MapDifference(map: Expr, keys: Expr) extends Expr 
 
   /* List operations */
   case class NilList(baseType: TypeTree) extends Expr 
@@ -152,24 +170,41 @@ object Trees {
   case class Concat(list1: Expr, list2: Expr) extends Expr 
   case class ListAt(list: Expr, index: Expr) extends Expr 
 
+  object UnaryOperator {
+    def unapply(expr: Expr) : Option[(Expr,(Expr)=>Expr)] = expr match {
+      case IsEmptySet(t) => Some((t,IsEmptySet))
+      case SetCardinality(t) => Some((t,SetCardinality))
+      case Car(t) => Some((t,Car))
+      case Cdr(t) => Some((t,Cdr))
+      case _ => None
+    }
+  }
+
   object BinaryOperator {
     def unapply(expr: Expr) : Option[(Expr,Expr,(Expr,Expr)=>Expr)] = expr match {
-        case Equals(t1,t2) => Some((t1,t2,Equals))
-        case Plus(t1,t2) => Some((t1,t2,Plus))
-        case Minus(t1,t2) => Some((t1,t2,Minus))
-        case Times(t1,t2) => Some((t1,t2,Times))
-        case Division(t1,t2) => Some((t1,t2,Division))
-        case LessThan(t1,t2) => Some((t1,t2,LessThan))
-        case GreaterThan(t1,t2) => Some((t1,t2,GreaterThan))
-        case LessEquals(t1,t2) => Some((t1,t2,LessEquals))
-        case GreaterEquals(t1,t2) => Some((t1,t2,GreaterEquals))
-        case ElementOfSet(t1,t2) => Some((t1,t2,ElementOfSet))
-        case SetEquals(t1,t2) => Some((t1,t2,SetEquals))
-        case SubsetOf(t1,t2) => Some((t1,t2,SubsetOf))
-        case SetIntersection(t1,t2) => Some((t1,t2,SetIntersection))
-        case SetUnion(t1,t2) => Some((t1,t2,SetUnion))
-        case SetDifference(t1,t2) => Some((t1,t2,SetDifference))
-        case _ => None
+      case Equals(t1,t2) => Some((t1,t2,Equals))
+      case Implies(t1,t2) => Some((t1,t2,Implies))
+      case Plus(t1,t2) => Some((t1,t2,Plus))
+      case Minus(t1,t2) => Some((t1,t2,Minus))
+      case Times(t1,t2) => Some((t1,t2,Times))
+      case Division(t1,t2) => Some((t1,t2,Division))
+      case LessThan(t1,t2) => Some((t1,t2,LessThan))
+      case GreaterThan(t1,t2) => Some((t1,t2,GreaterThan))
+      case LessEquals(t1,t2) => Some((t1,t2,LessEquals))
+      case GreaterEquals(t1,t2) => Some((t1,t2,GreaterEquals))
+      case ElementOfSet(t1,t2) => Some((t1,t2,ElementOfSet))
+      case SetEquals(t1,t2) => Some((t1,t2,SetEquals))
+      case SubsetOf(t1,t2) => Some((t1,t2,SubsetOf))
+      case SetIntersection(t1,t2) => Some((t1,t2,SetIntersection))
+      case SetUnion(t1,t2) => Some((t1,t2,SetUnion))
+      case SetDifference(t1,t2) => Some((t1,t2,SetDifference))
+      case SingletonMap(t1,t2) => Some((t1,t2,SingletonMap))
+      case MapGet(t1,t2) => Some((t1,t2,MapGet))
+      case MapUnion(t1,t2) => Some((t1,t2,MapUnion))
+      case MapDifference(t1,t2) => Some((t1,t2,MapDifference))
+      case Concat(t1,t2) => Some((t1,t2,Concat))
+      case ListAt(t1,t2) => Some((t1,t2,ListAt))
+      case _ => None
     }
   }
 }
diff --git a/src/purescala/TypeTrees.scala b/src/purescala/TypeTrees.scala
index 1e7c115bdec57567f6a0c0f9ff660216b4e363f3..caadcd2f8b30d08c48bd774252a84ca5865e4cfa 100644
--- a/src/purescala/TypeTrees.scala
+++ b/src/purescala/TypeTrees.scala
@@ -8,7 +8,7 @@ object TypeTrees {
   trait Typed {
     self =>
 
-    var _type: Option[TypeTree] = None
+    private var _type: Option[TypeTree] = None
 
     def getType: TypeTree = _type match {
       case None => NoType
@@ -21,6 +21,15 @@ object TypeTrees {
     }
   }
 
+  trait FixedType extends Typed {
+    self =>
+
+    val fixedType: TypeTree
+    override def getType: TypeTree = fixedType
+    override def setType(tt2: TypeTree) : self.type = this
+  }
+    
+
   sealed abstract class TypeTree {
     override def toString: String = PrettyPrinter(this)
   }
diff --git a/testcases/IntOperations.scala b/testcases/IntOperations.scala
index 03256597c78dc64b191e21b30c4f80d48e36557e..0c79ac4cc66d38ac35a5aacba1d00e68f5dec1cc 100644
--- a/testcases/IntOperations.scala
+++ b/testcases/IntOperations.scala
@@ -1,6 +1,6 @@
 object IntOperations {
     def sum(a: Int, b: Int) : Int = {
-        a + (if(b < 0) -b else b)
+        require(b >= 0)
+        a + b
     } ensuring(_ >= a)
-
 }