diff --git a/src/purescala/FairZ3Solver.scala b/src/purescala/FairZ3Solver.scala
index b34e87740ac7251837cb002f06147ee6c22122c4..ca3d666034d9c1387fabf303ba675590e2add74d 100644
--- a/src/purescala/FairZ3Solver.scala
+++ b/src/purescala/FairZ3Solver.scala
@@ -139,6 +139,8 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S
         case Int32Type => RegularSort(intSort)
         case AbstractClassType(d) => RegularSort(adtSorts(d))
         case CaseClassType(d) => RegularSort(adtSorts(d))
+        case SetType(d) => RegularSort(setSorts(d))
+        case mt @ MapType(d,r) => RegularSort(mapSorts(mt))
         case _ => throw UntranslatableTypeException("Can't handle type " + tt)
       }
 
@@ -1083,7 +1085,7 @@ class FairZ3Solver(reporter: Reporter) extends Solver(reporter) with AbstractZ3S
             }
             // case OpAsArray => {
             //   assert(argsSize == 0)
-            //   
+            //   throw new Exception()
             // }
             case other => {
               System.err.println("Don't know what to do with this declKind : " + other)
diff --git a/src/purescala/Z3ModelReconstruction.scala b/src/purescala/Z3ModelReconstruction.scala
index a3e15cbed7e888edec66c7241261ae3ee9a431d8..66b478d318fbfe2e8fed0b3b58ce5a27dde1a613 100644
--- a/src/purescala/Z3ModelReconstruction.scala
+++ b/src/purescala/Z3ModelReconstruction.scala
@@ -21,37 +21,49 @@ trait Z3ModelReconstruction {
     if(exprToZ3Id.isDefinedAt(id.toVariable)) {
       val z3ID : Z3AST = exprToZ3Id(id.toVariable)
 
-      expectedType match {
-        case BooleanType => model.evalAs[Boolean](z3ID).map(BooleanLiteral(_))
-        case Int32Type => model.evalAs[Int](z3ID).map(IntLiteral(_))
-        case MapType(kt,vt) => model.eval(z3ID) match {
+      def rec(ast: Z3AST, expTpe: TypeTree): Option[Expr] = expTpe match {
+        case BooleanType => model.evalAs[Boolean](ast).map(BooleanLiteral(_))
+        case Int32Type => model.evalAs[Int](ast).map(IntLiteral(_))
+        case MapType(kt,vt) => model.eval(ast) match {
           case None => None
           case Some(t) => model.getArrayValue(t) match {
             case None => None
             case Some((map, elseValue)) => 
               val singletons = map.map(e => (e, z3.getASTKind(e._2))).collect {
-                case ((index, value), Z3AppAST(someCons, arg :: Nil)) if someCons == mapRangeSomeConstructors(vt) => SingletonMap(fromZ3Formula(index), fromZ3Formula(arg))
+                case ((index, value), Z3AppAST(someCons, arg :: Nil)) if someCons == mapRangeSomeConstructors(vt) => SingletonMap(rec(index, kt).get, rec(arg, vt).get)
               }
-              (if (singletons.isEmpty) Some(EmptyMap(kt, vt)) else Some(FiniteMap(singletons.toSeq))).map(_.setType(expectedType))
+              (if (singletons.isEmpty) Some(EmptyMap(kt, vt)) else Some(FiniteMap(singletons.toSeq))).map(_.setType(expTpe))
           }
         }
-        case funType @ FunctionType(fts, tt) => model.eval(z3ID) match {
+        case funType @ FunctionType(fts, tt) => model.eval(ast) match {
           case None => None
           case Some(t) => model.getArrayValue(t) match {
             case None => None
             case Some((es, ev)) =>
               val entries: Seq[(Seq[Expr], Expr)] = es.toSeq.map(e => (e, z3.getASTKind(e._1))).collect {
-                case ((key, value), Z3AppAST(cons, args)) if cons == funDomainConstructors(funType) => (args map fromZ3Formula, fromZ3Formula(value))
+                case ((key, value), Z3AppAST(cons, args)) if cons == funDomainConstructors(funType) => ((args zip fts) map (p => rec(p._1, p._2).get), rec(value, tt).get)
               }
-              val elseValue = fromZ3Formula(ev)
-              Some(AnonymousFunction(entries, elseValue).setType(expectedType))
+              val elseValue = rec(ev, tt).get
+              Some(AnonymousFunction(entries, elseValue).setType(expTpe))
           }
         }
-        case other => model.eval(z3ID) match {
+        case SetType(dt) => model.eval(ast) match {
+          case None => None
+          case Some(t) => model.getSetValue(t) match {
+            case None => None
+            case Some(set) => {
+              val elems = set.map(e => rec(e, dt).get)
+              (if (elems.isEmpty) Some(EmptySet(dt)) else Some(FiniteSet(elems.toSeq))).map(_.setType(expTpe))
+            }
+          }
+        }
+        case other => model.eval(ast) match {
           case None => None
           case Some(t) => softFromZ3Formula(t)
         }
       }
+
+      rec(z3ID, expectedType)
     } else None
   }