diff --git a/library/proof/Internal.scala b/library/proof/Internal.scala
new file mode 100644
index 0000000000000000000000000000000000000000..3ac2903103998e0add424c95a8e213f23d94d5a4
--- /dev/null
+++ b/library/proof/Internal.scala
@@ -0,0 +1,61 @@
+/* Copyright 2009-2014 EPFL, Lausanne */
+package leon.proof
+
+import leon.lang._
+
+/** Internal helper classes and methods for the 'proof' package. */
+object Internal {
+
+  /*** Helper classes for relational reasoning ***/
+
+  case class WithRel[A, B](x: A, r: (A, B) => Boolean, prop: Boolean) {
+
+    /** Continue with the next relation. */
+    def ^^(y: B): RelReasoning[B] = {
+      require(prop ==> r(x, y))
+      RelReasoning(y, prop && r(x, y))
+    }
+
+    /** Add a proof. */
+    def ^^|(proof: Boolean): WithProof[A, B] = {
+      require(proof)
+      WithProof(x, r, proof, prop)
+    }
+
+    /** Short-hand for equational reasoning. */
+    def ==|(proof: Boolean): WithProof[A, A] = {
+      require(proof)
+      WithProof(x, _ == _, proof, prop)
+    }
+
+    def qed: Boolean = prop
+  }
+
+  case class WithProof[A, B](
+    x: A, r: (A, B) => Boolean, proof: Boolean, prop: Boolean) {
+
+    /** Close a proof. */
+    def |[C](that: WithProof[B, C]): WithProof[B, C] = {
+      require(this.prop && this.proof ==> this.r(this.x, that.x))
+      WithProof(
+        that.x, that.r, that.proof,
+        this.prop && this.proof && this.r(this.x, that.x))
+    }
+
+    /** Close a proof. */
+    def |[C](that: WithRel[B, C]): WithRel[B, C] = {
+      require(this.prop && this.proof ==> this.r(this.x, that.x))
+      WithRel(
+        that.x, that.r,
+        this.prop && this.proof && this.r(this.x, that.x))
+    }
+
+    /** Close a proof. */
+    def |(that: RelReasoning[B]): RelReasoning[B] = {
+      require(this.prop && this.proof ==> this.r(this.x, that.x))
+      RelReasoning(
+        that.x,
+        this.prop && this.proof && this.r(this.x, that.x))
+    }
+  }
+}
diff --git a/library/proof/package.scala b/library/proof/package.scala
new file mode 100644
index 0000000000000000000000000000000000000000..fd07a8128439127a8c80b6f977a4f01d162415d9
--- /dev/null
+++ b/library/proof/package.scala
@@ -0,0 +1,59 @@
+/* Copyright 2009-2014 EPFL, Lausanne */
+package leon
+
+import leon.annotation._
+import leon.lang._
+import scala.language.implicitConversions
+
+import leon.proof.Internal._
+
+package object proof {
+
+  case class ProofOps(prop: Boolean) {
+    def because(proof: Boolean): Boolean = proof && prop
+    def neverHolds: Boolean = {
+      require(!prop)
+      !prop
+    }
+  }
+
+  implicit def boolean2ProofOps(prop: Boolean): ProofOps = ProofOps(prop)
+
+  def trivial: Boolean = true
+
+  def by(proof: Boolean)(prop: Boolean): Boolean =
+    proof && prop
+
+  def check(prop: Boolean): Boolean = {
+    require(prop)
+    prop
+  }
+
+  /**
+   * Relational reasoning.
+   *
+   *         {
+   *           ((y :: ys) :+ x).last   ^^ _ == _ ^^| trivial         |
+   *           (y :: (ys :+ x)).last   ==| trivial         |
+   *           (ys :+ x).last          ==| snocLast(ys, x) |
+   *           x
+   *         }.qed
+   */
+  case class RelReasoning[A](x: A, prop: Boolean) {
+
+    def ^^[B](r: (A, B) => Boolean): WithRel[A, B] = WithRel(x, r, prop)
+
+    /** Short-hand for equational reasoning. */
+    def ==|(proof: Boolean): WithProof[A, A] = {
+      require(proof)
+      WithProof(x, _ == _, proof, prop)
+    }
+
+    def qed: Boolean = prop
+  }
+
+  implicit def any2RelReasoning[A](x: A): RelReasoning[A] =
+    RelReasoning(x, true)
+
+}
+