diff --git a/src/main/scala/leon/synthesis/Rules.scala b/src/main/scala/leon/synthesis/Rules.scala
index fa641566bf7a0205aab3c9c5b72940e35531ed87..cbc6f2974f90e66ac65ce2e6ddf8da185bc1a28b 100644
--- a/src/main/scala/leon/synthesis/Rules.scala
+++ b/src/main/scala/leon/synthesis/Rules.scala
@@ -11,6 +11,7 @@ object Rules {
     new Ground(synth),
     new CaseSplit(synth),
     new UnusedInput(synth),
+    new UnconstrainedOutput(synth),
     new Assert(synth)
   )
 }
@@ -148,16 +149,40 @@ class UnusedInput(synth: Synthesizer) extends Rule("UnusedInput", synth) {
     val unused = p.as.toSet -- variablesOf(p.phi)
 
     if (!unused.isEmpty) {
-        val sub = p.copy(as = p.as.filterNot(unused))
+      val sub = p.copy(as = p.as.filterNot(unused))
 
-        val onSuccess: List[Solution] => Solution = { 
-          case List(s) => s
-          case _ => Solution.none
-        }
+      val onSuccess: List[Solution] => Solution = { 
+        case List(s) => s
+        case _ => Solution.none
+      }
 
-        List(task.decompose(this, List(sub), onSuccess, 300))
+      List(task.decompose(this, List(sub), onSuccess, 300))
     } else {
       Nil
     }
   }
 }
+
+class UnconstrainedOutput(synth: Synthesizer) extends Rule("Unconstr.Output", synth) {
+  def defaultValueFor(id: Identifier): Expr = IntLiteral(0)
+
+  def isApplicable(task: Task): List[DecomposedTask] = {
+    val p = task.problem
+    val unconstr = p.xs.toSet -- variablesOf(p.phi)
+
+    if (!unconstr.isEmpty) {
+      val sub = p.copy(xs = p.xs.filterNot(unconstr))
+
+      val onSuccess: List[Solution] => Solution = { 
+        case List(s) => Solution(s.pre, LetTuple(sub.xs, s.term, Tuple(p.xs.map(id => if (unconstr(id)) defaultValueFor(id) else Variable(id) ))))
+        case _ => Solution.none
+      }
+
+      List(task.decompose(this, List(sub), onSuccess, 300))
+
+    } else {
+      Nil
+    }
+
+  }
+}