diff --git a/testcases/proof/proba/Coins.scala b/testcases/proof/proba/Coins.scala
index ff8bf91222b6493591be4e279a6069218c781d2f..0a84cb072700fe9a4070ec0ed4003b4596bb03d7 100644
--- a/testcases/proof/proba/Coins.scala
+++ b/testcases/proof/proba/Coins.scala
@@ -3,24 +3,29 @@ import leon.lang._
 
 object Coins {
 
-  /*
-   * number of outcomes for each face
-   */
-  case class CoinDist(pHead: BigInt, pTail: BigInt)
+  case class CoinDist(pHead: Rational) {
+    def pTail: Rational = Rational(1) - pHead
+  }
+
+  def isDist(dist: CoinDist): Boolean = 
+    dist.pHead.isRational && dist.pHead >= Rational(0) && dist.pHead <= Rational(1)
+
+
+  case class CoinsJoinDist(hh: Rational, ht: Rational, th: Rational, tt: Rational)
+
+  def isDist(dist: CoinsJoinDist): Boolean =
+    dist.hh.isRational && dist.hh >= Rational(0) && dist.hh <= Rational(1) &&
+    dist.ht.isRational && dist.ht >= Rational(0) && dist.ht <= Rational(1) &&
+    dist.th.isRational && dist.th >= Rational(0) && dist.th <= Rational(1) &&
+    dist.tt.isRational && dist.tt >= Rational(0) && dist.tt <= Rational(1) &&
+    (dist.hh + dist.ht + dist.th + dist.tt) ~ Rational(1)
 
-  case class CoinsJoinDist(hh: BigInt, ht: BigInt, th: BigInt, tt: BigInt)
 
   def isUniform(dist: CoinDist): Boolean = {
     require(isDist(dist))
-    dist.pHead == dist.pTail
+    dist.pHead ~ Rational(1, 2)
   }
 
-  def isDist(dist: CoinDist): Boolean = 
-    dist.pHead >= 0 && dist.pTail >= 0 && (dist.pHead > 0 || dist.pTail > 0)
-
-  def isDist(dist: CoinsJoinDist): Boolean =
-    dist.hh >= 0 && dist.ht >= 0 && dist.th >= 0 && dist.tt >= 0 &&
-    (dist.hh > 0 || dist.ht > 0 || dist.th > 0 || dist.tt > 0)
 
   def join(c1: CoinDist, c2: CoinDist): CoinsJoinDist =
     CoinsJoinDist(
@@ -29,82 +34,76 @@ object Coins {
       c1.pTail*c2.pHead,
       c1.pTail*c2.pTail)
 
-  def firstCoin(dist: CoinsJoinDist): CoinDist =
-    CoinDist(dist.hh + dist.ht, dist.th + dist.tt)
+  def firstCoin(dist: CoinsJoinDist): CoinDist = {
+    CoinDist(dist.hh + dist.ht)
+  } ensuring(res => res.pTail ~ (dist.th + dist.tt))
 
-  def secondCoin(dist: CoinsJoinDist): CoinDist =
-    CoinDist(dist.hh + dist.th, dist.ht + dist.tt)
+  def secondCoin(dist: CoinsJoinDist): CoinDist = {
+    CoinDist(dist.hh + dist.th)
+  } ensuring(res => res.pTail ~ (dist.ht + dist.tt))
 
   def isIndependent(dist: CoinsJoinDist): Boolean =
     join(firstCoin(dist), secondCoin(dist)) == dist
 
   def isEquivalent(dist1: CoinsJoinDist, dist2: CoinsJoinDist): Boolean = {
-    require(isDist(dist1) && dist1.hh > 0 && isDist(dist2) && dist2.hh > 0)
+    require(isDist(dist1) && isDist(dist2))
 
-    dist1.hh*dist2.hh == dist2.hh*dist1.hh &&
-    dist1.ht*dist2.hh == dist2.ht*dist1.hh &&
-    dist1.th*dist2.hh == dist2.th*dist1.hh &&
-    dist1.tt*dist2.hh == dist2.tt*dist1.hh
+    (dist1.hh ~ dist2.hh) &&
+    (dist1.ht ~ dist2.ht) &&
+    (dist1.th ~ dist2.th) &&
+    (dist1.tt ~ dist2.tt)
   }
 
 
-  case class CoinCondDist(ifHead: CoinDist, ifTail: CoinDist)
+  //case class CoinCondDist(ifHead: CoinDist, ifTail: CoinDist)
 
-  def condByFirstCoin(dist: CoinsJoinDist): CoinCondDist = {
-    CoinCondDist(
-      CoinDist(
-        dist.hh*(dist.th + dist.tt), //probability of head if head
-        dist.ht*(dist.th + dist.tt)  //probability of tail if head
-      ),
-      CoinDist(
-        dist.th*(dist.hh + dist.ht), //probability of head if tail
-        dist.tt*(dist.hh + dist.ht)  //probability of tail if tail
-      )
-    )
-  }
+  //def condByFirstCoin(dist: CoinsJoinDist): CoinCondDist = {
+  //  CoinCondDist(
+  //    CoinDist(
+  //      dist.hh*(dist.th + dist.tt), //probability of head if head
+  //      dist.ht*(dist.th + dist.tt)  //probability of tail if head
+  //    ),
+  //    CoinDist(
+  //      dist.th*(dist.hh + dist.ht), //probability of head if tail
+  //      dist.tt*(dist.hh + dist.ht)  //probability of tail if tail
+  //    )
+  //  )
+  //}
 
-  def combine(cond: CoinCondDist, dist: CoinDist): CoinsJoinDist = {
-    require(isDist(dist) && dist.pHead > 0 && dist.pTail > 0)
+  //def combine(cond: CoinCondDist, dist: CoinDist): CoinsJoinDist = {
+  //  require(isDist(dist) && dist.pHead > 0 && dist.pTail > 0)
 
-    val hh = cond.ifHead.pHead * dist.pHead
-    val ht = cond.ifHead.pTail * dist.pHead
-    val th = cond.ifTail.pHead * dist.pTail
-    val tt = cond.ifTail.pTail * dist.pTail
-    CoinsJoinDist(hh, ht, th, tt)
-  }
-  
-  def condIsSound(dist: CoinsJoinDist): Boolean = {
-    require(isDist(dist) && dist.hh > 0 && dist.ht > 0 && dist.th > 0 && dist.tt > 0)
+  //  val hh = cond.ifHead.pHead * dist.pHead
+  //  val ht = cond.ifHead.pTail * dist.pHead
+  //  val th = cond.ifTail.pHead * dist.pTail
+  //  val tt = cond.ifTail.pTail * dist.pTail
+  //  CoinsJoinDist(hh, ht, th, tt)
+  //}
+  //
+  //def condIsSound(dist: CoinsJoinDist): Boolean = {
+  //  require(isDist(dist) && dist.hh > 0 && dist.ht > 0 && dist.th > 0 && dist.tt > 0)
 
-    val computedDist = combine(condByFirstCoin(dist), firstCoin(dist))
-    isEquivalent(dist, computedDist)
-  } holds
+  //  val computedDist = combine(condByFirstCoin(dist), firstCoin(dist))
+  //  isEquivalent(dist, computedDist)
+  //} holds
 
 
   //should be INVALID
   def anyDistributionsNotEquivalent(dist1: CoinsJoinDist, dist2: CoinsJoinDist): Boolean = {
-    require(isDist(dist1) && isDist(dist2) && dist1.hh > 0 && dist2.hh > 0)
+    require(isDist(dist1) && isDist(dist2))
     isEquivalent(dist1, dist2)
   } holds
 
   //sum modulo: face is 0, tail is 1
   def sum(coin1: CoinDist, coin2: CoinDist): CoinDist = {
     require(isDist(coin1) && isDist(coin2))
-    CoinDist(
-      coin1.pHead*coin2.pHead + coin1.pTail*coin2.pTail,
-      coin1.pHead*coin2.pTail + coin1.pTail*coin2.pHead
-    )
-  }
+    CoinDist(coin1.pHead*coin2.pHead + coin1.pTail*coin2.pTail)
+  } ensuring(res => res.pTail ~ (coin1.pHead*coin2.pTail + coin1.pTail*coin2.pHead))
 
   def sum(dist: CoinsJoinDist): CoinDist = {
     require(isDist(dist))
-    CoinDist(
-      dist.hh + dist.tt,
-      dist.ht + dist.th
-    )
-  }
-
-  
+    CoinDist(dist.hh + dist.tt)
+  } ensuring(res => res.pTail ~ (dist.ht + dist.th))
 
 
 
@@ -113,73 +112,73 @@ object Coins {
    *          properties of sum operation            *
    ***************************************************/
 
-  def sumIsUniform1(coin1: CoinDist, coin2: CoinDist): Boolean = {
-    require(isDist(coin1) && isDist(coin2) && isUniform(coin1) && isUniform(coin2))
-    val dist = sum(coin1, coin2)
-    isUniform(dist)
-  } holds
-
-  def sumIsUniform2(coin1: CoinDist, coin2: CoinDist): Boolean = {
-    require(isDist(coin1) && isDist(coin2) && isUniform(coin1))
-    val dist = sum(coin1, coin2)
-    isUniform(dist)
-  } holds
-
-  def sumUniform3(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
-    require(isDist(coin1) && isDist(coin2) && isDist(coin3) && isUniform(coin1))
-    val dist = sum(sum(coin1, coin2), coin3)
-    isUniform(dist)
-  } holds
-
-  def sumUniformWithIndependence(dist: CoinsJoinDist): Boolean = {
-    require(isDist(dist) && isIndependent(dist) && (isUniform(firstCoin(dist)) || isUniform(secondCoin(dist))))
-    val res = sum(dist)
-    isUniform(res)
-  } holds
-
-  //should find counterexample, indepenence is required
-  def sumUniformWithoutIndependence(dist: CoinsJoinDist): Boolean = {
-    require(isDist(dist) && (isUniform(firstCoin(dist)) || isUniform(secondCoin(dist))))
-    val res = sum(dist)
-    isUniform(res)
-  } holds
-
-
-  //sum of two non-uniform dices is potentially uniform (no result)
-  def sumNonUniform1(coin1: CoinDist, coin2: CoinDist): Boolean = {
-    require(isDist(coin1) && isDist(coin2) && !isUniform(coin1) && !isUniform(coin2))
-    val dist = sum(coin1, coin2)
-    !isUniform(dist)
-  } holds
-
-  def sumNonUniform2(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
-    require(isDist(coin1) && isDist(coin2) && isDist(coin3) && !isUniform(coin1) && !isUniform(coin2) && !isUniform(coin3))
-    val dist = sum(sum(coin1, coin2), coin3)
-    !isUniform(dist)
-  } //holds
-
-  def sumNonUniformWithIndependence(dist: CoinsJoinDist): Boolean = {
-    require(isDist(dist) && isIndependent(dist) && !isUniform(firstCoin(dist)) && !isUniform(secondCoin(dist)))
-    val res = sum(dist)
-    !isUniform(res)
-  } holds
-
-  //independence is required
-  def sumNonUniformWithoutIndependence(dist: CoinsJoinDist): Boolean = {
-    require(isDist(dist) && !isUniform(firstCoin(dist)) && !isUniform(secondCoin(dist)))
-    val res = sum(dist)
-    !isUniform(res)
-  } holds
-
-
-  def sumIsCommutative(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
-    require(isDist(coin1) && isDist(coin2))
-    sum(coin1, coin2) == sum(coin2, coin1)
-  } holds
-
-  def sumIsAssociative(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
-    require(isDist(coin1) && isDist(coin2) && isDist(coin3))
-    sum(sum(coin1, coin2), coin3) == sum(coin1, sum(coin2, coin3))
-  } //holds
+  //def sumIsUniform1(coin1: CoinDist, coin2: CoinDist): Boolean = {
+  //  require(isDist(coin1) && isDist(coin2) && isUniform(coin1) && isUniform(coin2))
+  //  val dist = sum(coin1, coin2)
+  //  isUniform(dist)
+  //} holds
+
+  //def sumIsUniform2(coin1: CoinDist, coin2: CoinDist): Boolean = {
+  //  require(isDist(coin1) && isDist(coin2) && isUniform(coin1))
+  //  val dist = sum(coin1, coin2)
+  //  isUniform(dist)
+  //} holds
+
+  //def sumUniform3(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
+  //  require(isDist(coin1) && isDist(coin2) && isDist(coin3) && isUniform(coin1))
+  //  val dist = sum(sum(coin1, coin2), coin3)
+  //  isUniform(dist)
+  //} holds
+
+  //def sumUniformWithIndependence(dist: CoinsJoinDist): Boolean = {
+  //  require(isDist(dist) && isIndependent(dist) && (isUniform(firstCoin(dist)) || isUniform(secondCoin(dist))))
+  //  val res = sum(dist)
+  //  isUniform(res)
+  //} holds
+
+  ////should find counterexample, indepenence is required
+  //def sumUniformWithoutIndependence(dist: CoinsJoinDist): Boolean = {
+  //  require(isDist(dist) && (isUniform(firstCoin(dist)) || isUniform(secondCoin(dist))))
+  //  val res = sum(dist)
+  //  isUniform(res)
+  //} holds
+
+
+  ////sum of two non-uniform dices is potentially uniform (no result)
+  //def sumNonUniform1(coin1: CoinDist, coin2: CoinDist): Boolean = {
+  //  require(isDist(coin1) && isDist(coin2) && !isUniform(coin1) && !isUniform(coin2))
+  //  val dist = sum(coin1, coin2)
+  //  !isUniform(dist)
+  //} holds
+
+  //def sumNonUniform2(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
+  //  require(isDist(coin1) && isDist(coin2) && isDist(coin3) && !isUniform(coin1) && !isUniform(coin2) && !isUniform(coin3))
+  //  val dist = sum(sum(coin1, coin2), coin3)
+  //  !isUniform(dist)
+  //} //holds
+
+  //def sumNonUniformWithIndependence(dist: CoinsJoinDist): Boolean = {
+  //  require(isDist(dist) && isIndependent(dist) && !isUniform(firstCoin(dist)) && !isUniform(secondCoin(dist)))
+  //  val res = sum(dist)
+  //  !isUniform(res)
+  //} holds
+
+  ////independence is required
+  //def sumNonUniformWithoutIndependence(dist: CoinsJoinDist): Boolean = {
+  //  require(isDist(dist) && !isUniform(firstCoin(dist)) && !isUniform(secondCoin(dist)))
+  //  val res = sum(dist)
+  //  !isUniform(res)
+  //} holds
+
+
+  //def sumIsCommutative(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
+  //  require(isDist(coin1) && isDist(coin2))
+  //  sum(coin1, coin2) == sum(coin2, coin1)
+  //} holds
+
+  //def sumIsAssociative(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
+  //  require(isDist(coin1) && isDist(coin2) && isDist(coin3))
+  //  sum(sum(coin1, coin2), coin3) == sum(coin1, sum(coin2, coin3))
+  //} //holds
 
 }
diff --git a/testcases/proof/proba/ints/Coins.scala b/testcases/proof/proba/ints/Coins.scala
new file mode 100644
index 0000000000000000000000000000000000000000..ff8bf91222b6493591be4e279a6069218c781d2f
--- /dev/null
+++ b/testcases/proof/proba/ints/Coins.scala
@@ -0,0 +1,185 @@
+import leon.annotation._
+import leon.lang._
+
+object Coins {
+
+  /*
+   * number of outcomes for each face
+   */
+  case class CoinDist(pHead: BigInt, pTail: BigInt)
+
+  case class CoinsJoinDist(hh: BigInt, ht: BigInt, th: BigInt, tt: BigInt)
+
+  def isUniform(dist: CoinDist): Boolean = {
+    require(isDist(dist))
+    dist.pHead == dist.pTail
+  }
+
+  def isDist(dist: CoinDist): Boolean = 
+    dist.pHead >= 0 && dist.pTail >= 0 && (dist.pHead > 0 || dist.pTail > 0)
+
+  def isDist(dist: CoinsJoinDist): Boolean =
+    dist.hh >= 0 && dist.ht >= 0 && dist.th >= 0 && dist.tt >= 0 &&
+    (dist.hh > 0 || dist.ht > 0 || dist.th > 0 || dist.tt > 0)
+
+  def join(c1: CoinDist, c2: CoinDist): CoinsJoinDist =
+    CoinsJoinDist(
+      c1.pHead*c2.pHead,
+      c1.pHead*c2.pTail,
+      c1.pTail*c2.pHead,
+      c1.pTail*c2.pTail)
+
+  def firstCoin(dist: CoinsJoinDist): CoinDist =
+    CoinDist(dist.hh + dist.ht, dist.th + dist.tt)
+
+  def secondCoin(dist: CoinsJoinDist): CoinDist =
+    CoinDist(dist.hh + dist.th, dist.ht + dist.tt)
+
+  def isIndependent(dist: CoinsJoinDist): Boolean =
+    join(firstCoin(dist), secondCoin(dist)) == dist
+
+  def isEquivalent(dist1: CoinsJoinDist, dist2: CoinsJoinDist): Boolean = {
+    require(isDist(dist1) && dist1.hh > 0 && isDist(dist2) && dist2.hh > 0)
+
+    dist1.hh*dist2.hh == dist2.hh*dist1.hh &&
+    dist1.ht*dist2.hh == dist2.ht*dist1.hh &&
+    dist1.th*dist2.hh == dist2.th*dist1.hh &&
+    dist1.tt*dist2.hh == dist2.tt*dist1.hh
+  }
+
+
+  case class CoinCondDist(ifHead: CoinDist, ifTail: CoinDist)
+
+  def condByFirstCoin(dist: CoinsJoinDist): CoinCondDist = {
+    CoinCondDist(
+      CoinDist(
+        dist.hh*(dist.th + dist.tt), //probability of head if head
+        dist.ht*(dist.th + dist.tt)  //probability of tail if head
+      ),
+      CoinDist(
+        dist.th*(dist.hh + dist.ht), //probability of head if tail
+        dist.tt*(dist.hh + dist.ht)  //probability of tail if tail
+      )
+    )
+  }
+
+  def combine(cond: CoinCondDist, dist: CoinDist): CoinsJoinDist = {
+    require(isDist(dist) && dist.pHead > 0 && dist.pTail > 0)
+
+    val hh = cond.ifHead.pHead * dist.pHead
+    val ht = cond.ifHead.pTail * dist.pHead
+    val th = cond.ifTail.pHead * dist.pTail
+    val tt = cond.ifTail.pTail * dist.pTail
+    CoinsJoinDist(hh, ht, th, tt)
+  }
+  
+  def condIsSound(dist: CoinsJoinDist): Boolean = {
+    require(isDist(dist) && dist.hh > 0 && dist.ht > 0 && dist.th > 0 && dist.tt > 0)
+
+    val computedDist = combine(condByFirstCoin(dist), firstCoin(dist))
+    isEquivalent(dist, computedDist)
+  } holds
+
+
+  //should be INVALID
+  def anyDistributionsNotEquivalent(dist1: CoinsJoinDist, dist2: CoinsJoinDist): Boolean = {
+    require(isDist(dist1) && isDist(dist2) && dist1.hh > 0 && dist2.hh > 0)
+    isEquivalent(dist1, dist2)
+  } holds
+
+  //sum modulo: face is 0, tail is 1
+  def sum(coin1: CoinDist, coin2: CoinDist): CoinDist = {
+    require(isDist(coin1) && isDist(coin2))
+    CoinDist(
+      coin1.pHead*coin2.pHead + coin1.pTail*coin2.pTail,
+      coin1.pHead*coin2.pTail + coin1.pTail*coin2.pHead
+    )
+  }
+
+  def sum(dist: CoinsJoinDist): CoinDist = {
+    require(isDist(dist))
+    CoinDist(
+      dist.hh + dist.tt,
+      dist.ht + dist.th
+    )
+  }
+
+  
+
+
+
+
+  /***************************************************
+   *          properties of sum operation            *
+   ***************************************************/
+
+  def sumIsUniform1(coin1: CoinDist, coin2: CoinDist): Boolean = {
+    require(isDist(coin1) && isDist(coin2) && isUniform(coin1) && isUniform(coin2))
+    val dist = sum(coin1, coin2)
+    isUniform(dist)
+  } holds
+
+  def sumIsUniform2(coin1: CoinDist, coin2: CoinDist): Boolean = {
+    require(isDist(coin1) && isDist(coin2) && isUniform(coin1))
+    val dist = sum(coin1, coin2)
+    isUniform(dist)
+  } holds
+
+  def sumUniform3(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
+    require(isDist(coin1) && isDist(coin2) && isDist(coin3) && isUniform(coin1))
+    val dist = sum(sum(coin1, coin2), coin3)
+    isUniform(dist)
+  } holds
+
+  def sumUniformWithIndependence(dist: CoinsJoinDist): Boolean = {
+    require(isDist(dist) && isIndependent(dist) && (isUniform(firstCoin(dist)) || isUniform(secondCoin(dist))))
+    val res = sum(dist)
+    isUniform(res)
+  } holds
+
+  //should find counterexample, indepenence is required
+  def sumUniformWithoutIndependence(dist: CoinsJoinDist): Boolean = {
+    require(isDist(dist) && (isUniform(firstCoin(dist)) || isUniform(secondCoin(dist))))
+    val res = sum(dist)
+    isUniform(res)
+  } holds
+
+
+  //sum of two non-uniform dices is potentially uniform (no result)
+  def sumNonUniform1(coin1: CoinDist, coin2: CoinDist): Boolean = {
+    require(isDist(coin1) && isDist(coin2) && !isUniform(coin1) && !isUniform(coin2))
+    val dist = sum(coin1, coin2)
+    !isUniform(dist)
+  } holds
+
+  def sumNonUniform2(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
+    require(isDist(coin1) && isDist(coin2) && isDist(coin3) && !isUniform(coin1) && !isUniform(coin2) && !isUniform(coin3))
+    val dist = sum(sum(coin1, coin2), coin3)
+    !isUniform(dist)
+  } //holds
+
+  def sumNonUniformWithIndependence(dist: CoinsJoinDist): Boolean = {
+    require(isDist(dist) && isIndependent(dist) && !isUniform(firstCoin(dist)) && !isUniform(secondCoin(dist)))
+    val res = sum(dist)
+    !isUniform(res)
+  } holds
+
+  //independence is required
+  def sumNonUniformWithoutIndependence(dist: CoinsJoinDist): Boolean = {
+    require(isDist(dist) && !isUniform(firstCoin(dist)) && !isUniform(secondCoin(dist)))
+    val res = sum(dist)
+    !isUniform(res)
+  } holds
+
+
+  def sumIsCommutative(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
+    require(isDist(coin1) && isDist(coin2))
+    sum(coin1, coin2) == sum(coin2, coin1)
+  } holds
+
+  def sumIsAssociative(coin1: CoinDist, coin2: CoinDist, coin3: CoinDist): Boolean = {
+    require(isDist(coin1) && isDist(coin2) && isDist(coin3))
+    sum(sum(coin1, coin2), coin3) == sum(coin1, sum(coin2, coin3))
+  } //holds
+
+}
diff --git a/testcases/proof/proba/Dices.scala b/testcases/proof/proba/ints/Dices.scala
similarity index 100%
rename from testcases/proof/proba/Dices.scala
rename to testcases/proof/proba/ints/Dices.scala
diff --git a/testcases/proof/proba/FiniteDistributions.scala b/testcases/proof/proba/ints/FiniteDistributions.scala
similarity index 100%
rename from testcases/proof/proba/FiniteDistributions.scala
rename to testcases/proof/proba/ints/FiniteDistributions.scala
diff --git a/testcases/proof/proba/RandomVariables.scala b/testcases/proof/proba/ints/RandomVariables.scala
similarity index 100%
rename from testcases/proof/proba/RandomVariables.scala
rename to testcases/proof/proba/ints/RandomVariables.scala