diff --git a/testcases/verification/proof/Exponential.scala b/testcases/verification/proof/Exponential.scala
new file mode 100644
index 0000000000000000000000000000000000000000..d4bd7d61856dc5c49537b745f1263cb9319b20ce
--- /dev/null
+++ b/testcases/verification/proof/Exponential.scala
@@ -0,0 +1,205 @@
+/* Copyright 2009-2015 EPFL, Lausanne */
+
+package leon.testcases.verification.proof
+
+import leon.annotation._
+import leon.lang._
+import leon.proof._
+
+object Exponential {
+
+  /** A simple, but slow function for computing exponentials. */
+  def exp(x: BigInt, y: BigInt): BigInt = {
+    require(y >= 0)
+    if      (x == 0) 0
+    else if (y == 0) 1
+    else             x * exp(x, y - 1)
+  }
+
+  /** Exponentials of positive numbers are positive. */
+  def positive(x: BigInt, y: BigInt): Boolean = {
+    require(y >= 0 && x >= 0)
+    exp(x, y) >= 0 because {
+      if      (x == 0) trivial
+      else if (y == 0) trivial
+      else             check {
+        x * exp(x, y - 1) >= 0 because positive(x, y - 1)
+      }
+    }
+  }.holds
+
+  /** The exponential function is positive (shorter proof). */
+  def positiveShort(x: BigInt, y: BigInt): Boolean = {
+    require(y >= 0 && x > 0)
+    exp(x, y) >= 0 because {
+      if      (x == 0) trivial
+      else if (y == 0) trivial
+      else             positiveShort(x, y - 1)
+    }
+  }.holds
+
+  /**
+   * The exponential function (with respect to a fixed base) is a
+   * homomorphism between the commutative monoids of addition and
+   * multiplication over integers.
+   */
+  def monoidHom(x: BigInt, y: BigInt, z: BigInt): Boolean = {
+    require(y >= 0 && z >= 0)
+    exp(x, y + z) == exp(x, y) * exp(x, z) because {
+      if      (x == 0) trivial
+      else if (y == 0) trivial
+      else             {
+        exp(x, y + z)                 ==| (y + z != 0)           |
+        x * exp(x, y + z - 1)         ==| monoidHom(x, y - 1, z) |
+        x * exp(x, y - 1) * exp(x, z)
+      }.qed
+    }
+  }.holds
+
+  /**
+   * Exponentiation (by a fixed exponent) commutes with
+   * multiplication.
+   */
+  def expMultCommute(x: BigInt, y: BigInt, z: BigInt): Boolean = {
+    require(z >= 0)
+    exp(x * y, z) == exp(x, z) * exp(y, z) because {
+      if      (x == 0) trivial
+      else if (y == 0) trivial
+      else if (z == 0) trivial
+      else             check {
+        x * y * exp(x * y, z - 1) ==
+          x * exp(x, z - 1) * y * exp(y, z - 1) because
+          expMultCommute(x, y, z - 1)
+      }
+    }
+  }.holds
+
+  /** A combination of the previous two lemmas. */
+  def square(x: BigInt, y: BigInt): Boolean = {
+    require(y >= 0)
+    exp(x, 2 * y) == exp(x * x, y) because
+      monoidHom(x, y, y) && expMultCommute(x, x, y)
+  }.holds
+
+  /** A more efficient function for computing exponentials. */
+  def fastExp(x: BigInt, y: BigInt): BigInt = {
+    require(y >= 0)
+    if      (x == 0)     0
+    else if (y == 0)     1
+    else if (y % 2 == 0) fastExp(x * x, y / 2)
+    else                 x * fastExp(x, y - 1)
+  }
+
+  /**
+   * The two versions of the exponential function are equivalent.
+   *
+   * NOTE: Leon is able to verify most of the individual sub-goals of
+   * this correctness proof in fractions of a second using Z3-F, but
+   * often times out after >30s when trying to verify the overall
+   * post-condition (Intel core i7, Ubuntu 14.04.2 LTS, x86-64,
+   * 2015-06-04).
+   */
+  def fastExpCorrect(x: BigInt, y: BigInt): Boolean = {
+    require(y >= 0)
+    fastExp(x, y) == exp(x, y) because {
+      if      (x == 0)     trivial
+      else if (y == 0)     trivial
+      else if (y % 2 == 0) {
+        val z = y / 2; {
+          fastExp(x, y)         ==| trivial                  |
+          fastExp(x * x, z)     ==| fastExpCorrect(x * x, z) |
+          exp(x * x, z)         ==| square(x, z)             |
+          exp(x, y)
+        }.qed
+      }
+      else                 {
+        val z = (y - 1) / 2; {
+          fastExp(x, y)         ==| (y % 2 != 0)             |
+          x * fastExp(x * x, z) ==| {
+            fastExp(x * x, z)   ==| fastExpCorrect(x * x, z) |
+            exp(x * x, z)       ==| square(x, z)             |
+            exp(x, 2 * z)       ==| trivial                  |
+            exp(x, y - 1)                              }.qed |
+          x * exp(x, y - 1)     ==| (y != 0)                 |
+          exp(x, y)
+        }.qed
+      }
+    }
+  }.holds
+
+  /**
+   * The two versions of the exponential function are equivalent.
+   *
+   * NOTE: this version of the correctness proof is more verbose but
+   * easier to debug.  Leon is able to verify most of the individual
+   * sub-goals in fractions of a second using Z3-F, but often times
+   * out after >30s when trying to verify the overall post-condition
+   * (Intel core i7, Ubuntu 14.04.2 LTS, x86-64, 2015-06-04).
+   */
+  def fastExpCorrect2(x: BigInt, y: BigInt): Boolean = {
+    require(y >= 0)
+    fastExp(x, y) == exp(x, y) because {
+      if      (x == 0)     trivial
+      else if (y == 0)     trivial
+      else if (y % 2 == 0) {
+        val z = y / 2
+        check { fastExp(x, y)     == fastExp(x * x, z)                                   } &&
+        check { fastExp(x * x, z) == exp(x * x, z)     because fastExpCorrect2(x * x, z) } &&
+        check { exp(x * x, z)     == exp(x, y)         because square(x, z)              }
+      }
+      else                 {
+        val z = (y - 1) / 2;
+        check { fastExp(x, y)         == x * fastExp(x * x, z) because (y % 2 != 0)      } &&
+        check { x * fastExp(x * x, z) == x * exp(x, y - 1)     because {
+          check { fastExp(x * x, z)   == exp(x * x, z) because fastExpCorrect2(x * x, z) } &&
+          check { exp(x * x, z)       == exp(x, 2 * z) because square(x, z)              } &&
+          check { exp(x, 2 * z)       == exp(x, y - 1)                                   }
+        }                                                                                } &&
+        check { x * exp(x, y - 1)     == exp(x, y) because (y != 0) }
+      }
+    }
+  }.holds
+
+  /**
+   * A more efficient function for computing exponentials.
+   *
+   * NOTE: this version of fastExp incorporates the correctness proof
+   * directly into the post condition.  Leon is sometimes able to
+   * verify the post-condition in seconds using Z3-F, but often times
+   * out after >30s (Intel core i7, Ubuntu 14.04.2 LTS, x86-64,
+   * 2015-06-04).
+   */
+  def fastExp2(x: BigInt, y: BigInt): BigInt = {
+    require(y >= 0)
+    if      (x == 0)     BigInt(0)
+    else if (y == 0)     BigInt(1)
+    else if (y % 2 == 0) fastExp2(x * x, y / 2)
+    else                 x * fastExp2(x, y - 1)
+  } ensuring { res =>
+    res == exp(x, y) because {
+      if      (x == 0)     trivial
+      else if (y == 0)     trivial
+      else if (y % 2 == 0) {
+        val z = y / 2; {
+          res                    ==| trivial                 |
+          fastExp2(x * x, z)     ==| trivial /* ind. hyp. */ |
+          exp(x * x, z)          ==| square(x, z)            |
+          exp(x, y)
+        }.qed
+      }
+      else                 {
+        val z = (y - 1) / 2; {
+          res                    ==| (y % 2 != 0)            |
+          x * fastExp2(x * x, z) ==| {
+            fastExp2(x * x, z)   ==| trivial /* ind. hyp. */ |
+            exp(x * x, z)        ==| square(x, z)            |
+            exp(x, 2 * z)        ==| trivial                 |
+            exp(x, y - 1)                              }.qed |
+          x * exp(x, y - 1)      ==| (y != 0)                |
+          exp(x, y)
+        }.qed
+      }
+    }
+  }
+}
+