diff --git a/src/main/scala/inox/solvers/unrolling/LambdaTemplates.scala b/src/main/scala/inox/solvers/unrolling/LambdaTemplates.scala
index 0455d0fc8e1eeb1ff080a329584e71e630edadaf..d3f9e12cc78cea87bd77f638b44190c14b6bb4cd 100644
--- a/src/main/scala/inox/solvers/unrolling/LambdaTemplates.scala
+++ b/src/main/scala/inox/solvers/unrolling/LambdaTemplates.scala
@@ -170,7 +170,7 @@ trait LambdaTemplates { self: Templates =>
       */
     lazy val (key, instantiation) = {
       val (substMap, substInst) = Template.substitution(
-        condVars, exprVars, condTree, lambdas, quantifications, Map.empty, pathVar._1, pathVar._2)
+        condVars, exprVars, condTree, lambdas, quantifications, Map.empty, pathVar._2)
       val tmplInst = Template.instantiate(clauses, blockers, applications, matchers, substMap)
 
       val substituter = mkSubstituter(substMap.mapValues(_.encoded))
diff --git a/src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala b/src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala
index fa43474eadd42e50c5463fe78e39e73494ba0a42..faa160dffcfa052badfc5ea63c1eeb61122314e1 100644
--- a/src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala
+++ b/src/main/scala/inox/solvers/unrolling/QuantificationTemplates.scala
@@ -68,13 +68,13 @@ trait QuantificationTemplates { self: Templates =>
     */
   sealed abstract class Polarity {
     def substitute(substituter: Encoded => Encoded): Polarity = this match {
-      case Positive(guardVar) => Positive(guardVar)
+      case Positive(guard) => Positive(guard)
       case Negative(insts) => Negative(insts._1 -> substituter(insts._2))
-      case Unknown(qs, q2s, insts, guardVar) => Unknown(qs._1 -> substituter(qs._2), q2s, insts, guardVar)
+      case Unknown(qs, q2s, insts, guard) => Unknown(qs._1 -> substituter(qs._2), q2s, insts, guard)
     }
   }
 
-  case class Positive(guardVar: Encoded) extends Polarity
+  case class Positive(guard: Encoded) extends Polarity
   case class Negative(insts: (Variable, Encoded)) extends Polarity
 
   /** Unknown quantification polarity.
@@ -88,7 +88,7 @@ trait QuantificationTemplates { self: Templates =>
     * constructed where only certain `inst` variables are falsified. This is used to enable
     * a powerful unrolling heuristic in the presence of both quantifiers and recursive functions.
     */
-  case class Unknown(qs: (Variable, Encoded), q2s: (Variable, Encoded), insts: (Variable, Encoded), guardVar: Encoded) extends Polarity
+  case class Unknown(qs: (Variable, Encoded), q2s: (Variable, Encoded), insts: (Variable, Encoded), guard: Encoded) extends Polarity
 
   class QuantificationTemplate private[QuantificationTemplates] (
     val pathVar: (Variable, Encoded),
@@ -153,22 +153,24 @@ trait QuantificationTemplates { self: Templates =>
       proposition: Forall
     ): (Option[Variable], QuantificationTemplate) = {
 
-      val pT = mkEncoder(
-        condVars ++ exprVars + pathVar ++ quantifiers ++
-        substMap ++ lambdas.map(_.ids) ++ quantifications.flatMap(_.mapping)
-      )(p)
-
-      val (optVar, polarity, extraClauses, extraSubst) = optPol match {
+      val (optVar, polarity, extraGuarded, extraEqs, extraSubst): (
+        Option[Variable],
+        Polarity,
+        Map[Variable, Seq[Expr]],
+        Seq[Expr],
+        Map[Variable, Encoded]
+      ) = optPol match {
         case Some(true) =>
           val guard = encodeSymbol(Variable(FreshIdentifier("guard", true), BooleanType))
-          val extraClause = mkImplies(mkAnd(pathVar._2, guard), pT)
-          (None, Positive(guard), Seq(extraClause), Map(pathVar._1 -> guard))
+          val extraSubst = Map(pathVar._1 -> guard)
+          val extraGuarded = Map(pathVar._1 -> Seq(p))
+          (None, Positive(guard), extraGuarded, Seq.empty, extraSubst)
 
         case Some(false) =>
           val inst: Variable = Variable(FreshIdentifier("inst", true), BooleanType)
           val insts = inst -> encodeSymbol(inst)
-          val extraClause = mkImplies(pathVar._2, mkEquals(insts._2, pT))
-          (Some(inst), Negative(insts), Seq(extraClause), Map.empty[Variable, Encoded])
+          val extraGuarded = Map(pathVar._1 -> Seq(Equals(inst, p)))
+          (Some(inst), Negative(insts), extraGuarded, Seq.empty, Map(insts))
 
         case None =>
           val q: Variable = Variable(FreshIdentifier("q", true), BooleanType)
@@ -181,11 +183,8 @@ trait QuantificationTemplates { self: Templates =>
           val insts = inst -> encodeSymbol(inst)
 
           val polarity = Unknown(qs, q2s, insts, guard)
-          val extraClauses = Seq(
-            mkImplies(pathVar._2, mkEquals(qs._2, mkAnd(q2s._2, insts._2))),
-            mkImplies(pathVar._2, mkEquals(insts._2, mkImplies(guard, pT)))
-          )
-          (Some(q), polarity, extraClauses, Map(pathVar._1 -> guard))
+          val extraEqs = Seq(Equals(q, And(q2, inst)), Equals(inst, Implies(pathVar._1, p)))
+          (Some(q), polarity, Map.empty, extraEqs, Map(qs, q2s, insts) + (pathVar._1 -> guard))
       }
 
       // Note @nv: some hacky shit is going on here...
@@ -194,15 +193,16 @@ trait QuantificationTemplates { self: Templates =>
       // works due to [[Template.encode]] injecting `pathVar` BEFORE `substMap` into the
       // global encoding substitution.
       val (clauses, blockers, applications, matchers, templateString) =
-        Template.encode(pathVar, quantifiers, condVars, exprVars, guardedExprs,
-          equations, lambdas, quantifications, substMap = substMap ++ extraSubst)
+        Template.encode(pathVar, quantifiers, condVars, exprVars,
+          extraGuarded merge guardedExprs, extraEqs ++ equations,
+          lambdas, quantifications, substMap = substMap ++ extraSubst)
 
       val key = templateKey(proposition.args, proposition.body, substMap)
 
       (optVar, new QuantificationTemplate(
-        pathVar, polarity, quantifiers, condVars, exprVars, condTree,
-        extraClauses ++ clauses, blockers, applications, matchers, lambdas, quantifications, key,
-        proposition.body, () => "Template for " + proposition + " is :\n" + templateString()))
+        pathVar, polarity, quantifiers, condVars, exprVars, condTree, clauses,
+        blockers, applications, matchers, lambdas, quantifications, key, proposition.body,
+        () => "Template for " + proposition + " is :\n" + templateString()))
     }
   }
 
@@ -467,7 +467,8 @@ trait QuantificationTemplates { self: Templates =>
     if (es.isEmpty) trueT else mkAnd(es.toSeq.sortBy(_.toString) : _*)
 
   private[solvers] trait Quantification extends IncrementalState {
-    val pathVar: (Variable, Encoded)
+    val blocker: Encoded
+    val guard: Encoded
     val quantifiers: Seq[(Variable, Encoded)]
     val condVars: Map[Variable, Encoded]
     val exprVars: Map[Variable, Encoded]
@@ -483,8 +484,7 @@ trait QuantificationTemplates { self: Templates =>
     val body: Expr
 
     lazy val quantified: Set[Encoded] = quantifiers.map(_._2).toSet
-    lazy val start = pathVar._2
-    lazy val pathBlockers = blockerPath(start)
+    lazy val pathBlockers = blockerPath(blocker)
 
     private val constraints: Seq[(Encoded, MatcherKey, Int)] = (for {
       (_, ms) <- matchers
@@ -587,7 +587,7 @@ trait QuantificationTemplates { self: Templates =>
       for (p @ (bs, subst, delay) <- substs if !handledSubsts.get(this).exists(_ contains (bs -> subst))) {
         val totalDelay = delay + (3 * subst.values.collect { case Right(m) => totalDepth(m) }.sum)
         if (totalDelay > 0) {
-          val gen = currentGeneration + totalDelay
+          val gen = currentGeneration + totalDelay + (if (this.isInstanceOf[GeneralQuantification]) 2 else 0)
           ignoredSubsts += this -> (ignoredSubsts.getOrElse(this, Set.empty) + ((gen, bs, subst)))
         } else {
           instantiation ++= instantiateSubst(bs, subst)
@@ -606,7 +606,7 @@ trait QuantificationTemplates { self: Templates =>
 
       val baseSubst = subst ++ instanceSubst(enabler).mapValues(Left(_))
       val (substMap, substClauses) = Template.substitution(
-        condVars, exprVars, condTree, lambdas, quantifications, baseSubst, pathVar._1, enabler)
+        condVars, exprVars, condTree, lambdas, quantifications, baseSubst, enabler)
       instantiation ++= substClauses
 
       val msubst = substMap.collect { case (c, Right(m)) => c -> m }
@@ -617,17 +617,17 @@ trait QuantificationTemplates { self: Templates =>
       instantiation ++= Template.instantiate(clauses, blockers, applications, Map.empty, substMap)
 
       for ((b,ms) <- matchers; m <- ms) {
-        val sb = bs ++ (if (b == start) Set.empty else Set(substituter(b)))
+        val sb = bs ++ (if (b == guard) Set.empty else Set(substituter(b)))
         val sm = m.substitute(substituter, msubst)
 
         def abs(i: Int): Int = if (i < 0) -i else i
-        val nextGeneration: Int = currentGeneration +
-          2 * (abs(totalDepth(sm) - totalDepth(m)) + (if (b == start) 0 else 1))
+        val totalDelay = 2 * (abs(totalDepth(sm) - totalDepth(m)) + (if (b == guard) 0 else 1))
 
-        if (nextGeneration == currentGeneration) {
-          instantiation ++= instantiateMatcher(sb, sm)
+        if (totalDelay > 0) {
+          val gen = currentGeneration + totalDelay + (if (this.isInstanceOf[GeneralQuantification]) 2 else 0)
+          ignoredMatchers += ((gen, sb, sm))
         } else {
-          ignoredMatchers += ((nextGeneration, sb, sm))
+          instantiation ++= instantiateMatcher(sb, sm)
         }
       }
 
@@ -693,11 +693,11 @@ trait QuantificationTemplates { self: Templates =>
   }
 
   private class GeneralQuantification (
-    val pathVar: (Variable, Encoded),
+    val blocker: Encoded,
     val qs: (Variable, Encoded),
     val q2s: (Variable, Encoded),
     val insts: (Variable, Encoded),
-    val guardVar: Encoded,
+    val guard: Encoded,
     val quantifiers: Seq[(Variable, Encoded)],
     val condVars: Map[Variable, Encoded],
     val exprVars: Map[Variable, Encoded],
@@ -717,11 +717,10 @@ trait QuantificationTemplates { self: Templates =>
     private var _insts: Map[Encoded, Set[Encoded]] = Map.empty
     def instantiations = _insts
 
-    private val blocker = Variable(FreshIdentifier("b_fresh", true), BooleanType)
     protected def instanceSubst(enabler: Encoded): Map[Encoded, Encoded] = {
       val nextQ2Var = encodeSymbol(q2s._1)
 
-      val subst = Map(qs._2 -> currentQ2Var, guardVar -> enabler,
+      val subst = Map(qs._2 -> currentQ2Var, guard -> enabler,
         q2s._2 -> nextQ2Var, insts._2 -> encodeSymbol(insts._1))
 
       _currentQ2Var = nextQ2Var
@@ -736,8 +735,8 @@ trait QuantificationTemplates { self: Templates =>
   }
 
   private class Axiom (
-    val pathVar: (Variable, Encoded),
-    val guardVar: Encoded,
+    val blocker: Encoded,
+    val guard: Encoded,
     val quantifiers: Seq[(Variable, Encoded)],
     val condVars: Map[Variable, Encoded],
     val exprVars: Map[Variable, Encoded],
@@ -753,7 +752,7 @@ trait QuantificationTemplates { self: Templates =>
     val holds = trueT
 
     protected def instanceSubst(enabler: Encoded): Map[Encoded, Encoded] = {
-      Map(guardVar -> enabler)
+      Map(guard -> enabler)
     }
   }
 
@@ -820,8 +819,8 @@ trait QuantificationTemplates { self: Templates =>
       case None =>
         val clauses = new scala.collection.mutable.ListBuffer[Encoded]
         val mapping: Map[Encoded, Encoded] = template.polarity match {
-          case Positive(guardVar) =>
-            val axiom = new Axiom(template.pathVar, guardVar,
+          case Positive(guard) =>
+            val axiom = new Axiom(template.pathVar._2, guard,
               template.quantifiers, template.condVars, template.exprVars, template.condTree,
               template.clauses, template.blockers, template.applications, template.matchers,
               template.lambdas, template.quantifications, template.body)
@@ -841,7 +840,7 @@ trait QuantificationTemplates { self: Templates =>
             val (substMap, substClauses) = Template.substitution(
               template.condVars, template.exprVars, template.condTree,
               template.lambdas, template.quantifications,
-              Map(insts._2 -> Left(instT)), template.pathVar._1, template.pathVar._2)
+              Map(insts._2 -> Left(instT)), template.pathVar._2)
             clauses ++= substClauses
 
             // this will call `instantiateMatcher` on all matchers in `template.matchers`
@@ -851,12 +850,12 @@ trait QuantificationTemplates { self: Templates =>
 
             Map(insts._2 -> instT)
 
-          case Unknown(qs, q2s, insts, guardVar) =>
+          case Unknown(qs, q2s, insts, guard) =>
             val qT = encodeSymbol(qs._1)
             val substituter = mkSubstituter(Map(qs._2 -> qT))
 
-            val quantification = new GeneralQuantification(template.pathVar,
-              qs._1 -> qT, q2s, insts, guardVar,
+            val quantification = new GeneralQuantification(template.pathVar._2,
+              qs._1 -> qT, q2s, insts, guard,
               template.quantifiers, template.condVars, template.exprVars, template.condTree,
               template.clauses map substituter, // one clause depends on 'qs._2' (and therefore 'qT')
               template.blockers, template.applications, template.matchers,
@@ -904,7 +903,7 @@ trait QuantificationTemplates { self: Templates =>
       ignoredMatchers += ((gen - diff, bs, m))
     }
 
-    for (q <- quantifications) {
+    for (q <- quantifications if ignoredSubsts.isDefinedAt(q)) {
       ignoredSubsts += q -> ignoredSubsts(q).map { case (gen, bs, subst) => (gen - diff, bs, subst) }
     }
   }
diff --git a/src/main/scala/inox/solvers/unrolling/Templates.scala b/src/main/scala/inox/solvers/unrolling/Templates.scala
index 5b7466c51db5d686298a8c45d86c742ca3a5b2d4..34406c5a6589c8df369f768c5b39bbc646ce1fa3 100644
--- a/src/main/scala/inox/solvers/unrolling/Templates.scala
+++ b/src/main/scala/inox/solvers/unrolling/Templates.scala
@@ -312,7 +312,7 @@ trait Templates extends TemplateGenerator
     def instantiate(aVar: Encoded, args: Seq[Arg]): Clauses = {
       val (substMap, clauses) = Template.substitution(
         condVars, exprVars, condTree, lambdas, quantifications,
-        (this.args zip args).toMap + (start -> Left(aVar)), pathVar._1, aVar)
+        (this.args zip args).toMap + (start -> Left(aVar)), aVar)
       clauses ++ instantiate(substMap)
     }
 
@@ -372,7 +372,8 @@ trait Templates extends TemplateGenerator
         var applications : Map[Variable, Set[App]]     = Map.empty
         var matchers     : Map[Variable, Set[Matcher]] = Map.empty
 
-        for ((b,es) <- guardedExprs) {
+        val pv = pathVar._1
+        for ((b,es) <- guardedExprs + (pv -> (guardedExprs.getOrElse(pv, Set.empty) ++ equations))) {
           var funInfos   : Set[Call]    = Set.empty
           var appInfos   : Set[App]     = Set.empty
           var matchInfos : Set[Matcher] = Set.empty
@@ -410,7 +411,6 @@ trait Templates extends TemplateGenerator
             }
 
             matchInfos ++= exprToMatcher.values
-            clauses :+= encoder(Implies(b, e))
           }
 
           val calls = funInfos.filter(i => Some(i) != optIdCall)
@@ -426,6 +426,7 @@ trait Templates extends TemplateGenerator
           if (matchs.nonEmpty) matchers += b -> matchs
         }
 
+        clauses ++= (for ((b,es) <- guardedExprs; e <- es) yield encoder(Implies(b, e)))
         clauses ++= equations.map(encoder)
 
         (clauses, blockers, applications, matchers merge optIdMatcher.map(m => pathVar._1 -> Set(m)).toMap)
@@ -469,7 +470,6 @@ trait Templates extends TemplateGenerator
       lambdas: Seq[LambdaTemplate],
       quantifications: Seq[QuantificationTemplate],
       baseSubst: Map[Encoded, Arg],
-      pathVar: Variable,
       aVar: Encoded
     ): (Map[Encoded, Arg], Clauses) = {
 
@@ -563,7 +563,7 @@ trait Templates extends TemplateGenerator
       start -> encodedStart, bindings.toSeq, condVars, exprVars, guardedExprs, eqs, lambdas, quants)
 
     val (substMap, substClauses) = Template.substitution(
-      condVars, exprVars, condTree, lambdas, quants, Map.empty, start, encodedStart)
+      condVars, exprVars, condTree, lambdas, quants, Map.empty, encodedStart)
 
     val templateClauses = Template.instantiate(clauses, calls, apps, matchers, substMap)
     val allClauses = encodedStart +: (tpeClauses ++ substClauses ++ templateClauses)
diff --git a/src/main/scala/inox/utils/IncrementalMap.scala b/src/main/scala/inox/utils/IncrementalMap.scala
index c62104ae82e5a1b7462633c000d9fa7d093d6747..15cb2e6ab5aa03467ad6782a77d121f806fcbd53 100644
--- a/src/main/scala/inox/utils/IncrementalMap.scala
+++ b/src/main/scala/inox/utils/IncrementalMap.scala
@@ -20,6 +20,7 @@ class IncrementalMap[A, B] private(dflt: Option[B])
 
   override def clear(): Unit = {
     stack.clear()
+    push()
   }
 
   def reset(): Unit = {