From c0785649c58f5bd8cc9d1aeb5e0805852574189f Mon Sep 17 00:00:00 2001 From: Regis Blanc <regwblanc@gmail.com> Date: Tue, 14 Jul 2015 09:47:58 +0200 Subject: [PATCH] rational invariant positive denominator --- library/lang/Rational.scala | 63 +++++++------------ .../verification/math/RationalProps.scala | 2 + 2 files changed, 24 insertions(+), 41 deletions(-) diff --git a/library/lang/Rational.scala b/library/lang/Rational.scala index e2d6f7588..c8027dee9 100644 --- a/library/lang/Rational.scala +++ b/library/lang/Rational.scala @@ -12,32 +12,34 @@ case class Rational(numerator: BigInt, denominator: BigInt) { def +(that: Rational): Rational = { require(this.isRational && that.isRational) Rational(this.numerator*that.denominator + that.numerator*this.denominator, this.denominator*that.denominator) - } + } ensuring(res => res.isRational) def -(that: Rational): Rational = { require(this.isRational && that.isRational) Rational(this.numerator*that.denominator - that.numerator*this.denominator, this.denominator*that.denominator) - } + } ensuring(res => res.isRational) def unary_- : Rational = { require(this.isRational) Rational(-this.numerator, this.denominator) - } + } ensuring(res => res.isRational) def *(that: Rational): Rational = { require(this.isRational && that.isRational) Rational(this.numerator*that.numerator, this.denominator*that.denominator) - } + } ensuring(res => res.isRational) def /(that: Rational): Rational = { require(this.isRational && that.isRational && that.nonZero) - Rational(this.numerator*that.denominator, this.denominator*that.numerator) - } + val newNumerator = this.numerator*that.denominator + val newDenominator = this.denominator*that.numerator + normalize(newNumerator, newDenominator) + } ensuring(res => res.isRational) def reciprocal: Rational = { require(this.isRational && this.nonZero) - Rational(this.denominator, this.numerator) - } + normalize(this.denominator, this.numerator) + } ensuring(res => res.isRational) def ~(that: Rational): Boolean = { @@ -47,50 +49,22 @@ case class Rational(numerator: BigInt, denominator: BigInt) { def <(that: Rational): Boolean = { require(this.isRational && that.isRational) - if(this.denominator >= 0 && that.denominator >= 0) - this.numerator*that.denominator < that.numerator*this.denominator - else if(this.denominator >= 0 && that.denominator < 0) - this.numerator*that.denominator > that.numerator*this.denominator - else if(this.denominator < 0 && that.denominator >= 0) - this.numerator*that.denominator > that.numerator*this.denominator - else - this.numerator*that.denominator < that.numerator*this.denominator + this.numerator*that.denominator < that.numerator*this.denominator } def <=(that: Rational): Boolean = { require(this.isRational && that.isRational) - if(this.denominator >= 0 && that.denominator >= 0) - this.numerator*that.denominator <= that.numerator*this.denominator - else if(this.denominator >= 0 && that.denominator < 0) - this.numerator*that.denominator >= that.numerator*this.denominator - else if(this.denominator < 0 && that.denominator >= 0) - this.numerator*that.denominator >= that.numerator*this.denominator - else - this.numerator*that.denominator <= that.numerator*this.denominator + this.numerator*that.denominator <= that.numerator*this.denominator } def >(that: Rational): Boolean = { require(this.isRational && that.isRational) - if(this.denominator >= 0 && that.denominator >= 0) - this.numerator*that.denominator > that.numerator*this.denominator - else if(this.denominator >= 0 && that.denominator < 0) - this.numerator*that.denominator < that.numerator*this.denominator - else if(this.denominator < 0 && that.denominator >= 0) - this.numerator*that.denominator < that.numerator*this.denominator - else - this.numerator*that.denominator > that.numerator*this.denominator + this.numerator*that.denominator > that.numerator*this.denominator } def >=(that: Rational): Boolean = { require(this.isRational && that.isRational) - if(this.denominator >= 0 && that.denominator >= 0) - this.numerator*that.denominator >= that.numerator*this.denominator - else if(this.denominator >= 0 && that.denominator < 0) - this.numerator*that.denominator <= that.numerator*this.denominator - else if(this.denominator < 0 && that.denominator >= 0) - this.numerator*that.denominator <= that.numerator*this.denominator - else - this.numerator*that.denominator >= that.numerator*this.denominator + this.numerator*that.denominator >= that.numerator*this.denominator } def nonZero: Boolean = { @@ -98,7 +72,14 @@ case class Rational(numerator: BigInt, denominator: BigInt) { numerator != 0 } - def isRational: Boolean = denominator != 0 + def isRational: Boolean = denominator > 0 + + private def normalize(num: BigInt, den: BigInt): Rational = { + if(den < 0) + Rational(-num, -den) + else + Rational(num, den) + } } object Rational { diff --git a/testcases/verification/math/RationalProps.scala b/testcases/verification/math/RationalProps.scala index e84b92361..60d30a6c6 100644 --- a/testcases/verification/math/RationalProps.scala +++ b/testcases/verification/math/RationalProps.scala @@ -2,6 +2,8 @@ import leon.lang._ import leon.collection._ import leon._ +import scala.language.postfixOps + object RationalProps { def squarePos(r: Rational): Rational = { -- GitLab