// @(#)$Id: NaturalNumber.java,v 1.26 2007/06/29 21:01:58 chalin Exp $
// Copyright (C) 2005 Iowa State University
//
// This file is part of the runtime library of the Java Modeling Language.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation; either version 2.1,
// of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with JML; see the file LesserGPL.txt. If not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
// 02110-1301 USA.
package org.jmlspecs.unfinished.resolve;
import java.math.BigInteger;
/** The natural numbers. These are essentially unlimited in size.
*
* @version $Revision: 1.26 $
* @author Gary T. Leavens
* @see java.math.BigInteger
* @see org.jmlspecs.models.JMLFiniteInteger
*/
public /*@ pure @*/ class NaturalNumber extends Number
implements TotallyOrderedCompareTo, org.jmlspecs.models.JMLType
{
private static final long serialVersionUID = -388120386774993267L;
/** The value of this natural number. */
private final /*@ non_null @*/ BigInteger value;
//@ in objectState;
//@ private constraint_redundantly value == \old(value);
//@ private invariant value.compareTo(BigInteger.ZERO) >= 0;
//@ public invariant owner == null;
/** Initialize this natural number to zero.
* @see #ZERO
* @see #NaturalNumber(long)
* @see #NaturalNumber(BigInteger)
*/
/*@ public normal_behavior
@ assignable objectState, owner;
@ ensures isZero();
@*/
public NaturalNumber () {
//@ set owner = null;
//@ assume BigInteger.ZERO != null;
value = BigInteger.ZERO;
}
/** Initialize this natural number to the given long value.
* @see #NaturalNumber()
* @see #NaturalNumber(BigInteger)
* @see #valueOf(long)
*/
/*@ public normal_behavior
@ requires val >= 0;
@ assignable objectState, owner;
@ ensures longValue() == val;
@*/
//@ also
//@ exsures (IllegalArgumentException) val < 0;
public NaturalNumber (long val)
throws IllegalArgumentException
{
//@ set owner = null;
if (val >= 0) {
value = BigInteger.valueOf(val); //@ nowarn NonNull;
} else {
throw new IllegalArgumentException();
}
}
/** Initialize this natural number to the given {@link
* java.math.BigInteger} value.
* @see #NaturalNumber()
* @see #NaturalNumber(BigInteger)
*/
/*@ public normal_behavior
@ requires val != null && val.compareTo(BigInteger.ZERO) >= 0;
@ assignable objectState, owner;
@ ensures bigIntegerValue().equals(val);
@*/
public NaturalNumber(/*@ non_null @*/ BigInteger val)
throws IllegalArgumentException
{
//@ set owner = null;
if (val.compareTo(BigInteger.ZERO) >= 0) {
value = val;
} else {
throw new IllegalArgumentException();
}
}
// Static Factory Methods
/** Return a natural number with the given value.
* @see #NaturalNumber(long)
* @see #NaturalNumber(BigInteger)
*/
/*@ public normal_behavior
@ requires val >= 0;
@ ensures \result != null
@ && \result.equals(new NaturalNumber(val));
@*/
//@ implies_that
//@ requires val >= 0;
public static /*@ pure @*/
/*@ non_null @*/ NaturalNumber valueOf(long val)
{
return new NaturalNumber(val);
}
/** The natural number zero.
* @see #NaturalNumber()
* @see #ONE
*/
public static final /*@ non_null @*/ NaturalNumber ZERO = valueOf(0);
/** The natural number one.
* @see #NaturalNumber(long)
* @see #valueOf(long)
* @see #ZERO
*/
public static final /*@ non_null @*/ NaturalNumber ONE = valueOf(1);
//@ public invariant ZERO != null && ZERO.equals(valueOf(0));
//@ public constraint ZERO == \old(ZERO);
//@ public invariant ONE != null && ONE.equals(valueOf(1));
//@ public constraint ONE == \old(ONE);
// Arithmetic Operations
/** Return the successor of this natural number.
* @see #suc(NaturalNumber)
* @see #add
* @see #ONE
*/
/*@ public normal_behavior
@ ensures \result != null && \result.equals(this.add(ONE));
@*/
public /*@ non_null @*/ NaturalNumber suc() {
return add(ONE);
}
/** Return the successor of the given natural number.
* @see #suc()
* @see #add
*/
/*@ public normal_behavior
@ requires v != null;
@ ensures \result != null && \result.equals(v.suc());
@ ensures_redundantly \result != null
@ && \result.equals(v.add(ONE));
@*/
public static /*@ pure @*/ /*@ non_null @*/
NaturalNumber suc(/*@ non_null @*/ NaturalNumber v)
{
return v.suc();
}
/** Return the sum of this natural number and the given one.
* @see #suc()
* @see #add
*/
/*@ public normal_behavior
@ requires val != null;
@ {|
@ requires val.equals(ZERO);
@ ensures \result != null && \result.equals(this);
@ also
@ forall NaturalNumber v;
@ requires !(val.equals(ZERO));
@ ensures v != null && v.suc().equals(val)
@ ==> \result != null
@ && \result.equals(this.add(v).suc());
@ |}
@ for_example
@ public normal_example
@ requires val != null && val.equals(new NaturalNumber(3))
@ && this.equals(new NaturalNumber(7));
@ ensures \result != null && \result.equals(new NaturalNumber(10));
@*/
public /*@ non_null @*/
NaturalNumber add(/*@ non_null @*/ NaturalNumber val)
{
return new NaturalNumber(value.add(val.value)); //@ nowarn NonNull;
} //@ nowarn Exception;
/** Return the product of this natural number and the given one.
* @see #divide
*/
/*@ public normal_behavior
@ requires val != null;
@ {|
@ requires val.equals(ZERO);
@ ensures \result != null && \result.isZero();
@ also
@ forall NaturalNumber v;
@ requires !(val.equals(ZERO));
@ ensures v != null && v.suc().equals(val)
@ ==> \result != null
@ && \result.equals(this.add(this.multiply(v)));
@ |}
@ implies_that
@ public normal_behavior
@ requires val != null && val.equals(ONE);
@ ensures \result != null && \result.equals(this);
@ for_example
@ public normal_example
@ requires val != null && val.equals(new NaturalNumber(3))
@ && this.equals(new NaturalNumber(7));
@ ensures \result != null && \result.equals(new NaturalNumber(21));
@*/
public /*@ non_null @*/
NaturalNumber multiply(/*@ non_null @*/ NaturalNumber val)
{
return new NaturalNumber(value.multiply(val.value));//@ nowarn NonNull;
} //@ nowarn Exception;
/** Return the quotient of this natural number divided by the given one.
* @see #multiply
*/
/*@ public normal_behavior
@ forall NaturalNumber quot, rem;
@ requires val != null && !val.equals(ZERO);
@ ensures quot != null && rem != null && rem.compareTo(this) < 0
@ && this.equals(rem.add(quot.multiply(val)))
@ ==> \result.equals(quot);
@ also
@ public exceptional_behavior
@ requires val != null && val.equals(ZERO);
@ signals_only ArithmeticException;
@ implies_that
@ public normal_behavior
@ requires val != null && val.equals(ONE);
@ ensures \result != null && \result.equals(this);
@ for_example
@ public normal_example
@ requires val != null && val.equals(new NaturalNumber(3))
@ && this.equals(new NaturalNumber(22));
@ ensures \result != null && \result.equals(new NaturalNumber(7));
@*/
public /*@ non_null @*/
NaturalNumber divide(/*@ non_null @*/ NaturalNumber val)
{
return new NaturalNumber(value.divide(val.value)); //@ nowarn NonNull;
} //@ nowarn Exception;
/** Return the remainder of this natural number divided by the given one.
* @see #divide
*/
/*@ public normal_behavior
@ forall NaturalNumber quot, rem;
@ requires val != null && !val.equals(ZERO);
@ ensures quot != null && rem != null && rem.compareTo(this) < 0
@ && this.equals(rem.add(quot.multiply(val)))
@ ==> \result.equals(rem);
@ also
@ public exceptional_behavior
@ requires val != null && val.equals(ZERO);
@ signals_only ArithmeticException;
@ implies_that
@ public normal_behavior
@ requires val != null && val.equals(ONE);
@ ensures \result != null && \result.equals(ZERO);
@ for_example
@ public normal_example
@ requires val != null && val.equals(new NaturalNumber(3))
@ && this.equals(new NaturalNumber(22));
@ ensures \result != null && \result.equals(new NaturalNumber(1));
@*/
public /*@ non_null @*/
NaturalNumber remainder(/*@ non_null @*/ NaturalNumber val)
{
return new NaturalNumber(value.remainder(val.value));//@ nowarn NonNull;
} //@ nowarn Exception;
/** Return this natural number multiplied by itself the given
* number of times.
* @see #multiply
* @see #pow(int)
*/
/*@ public normal_behavior
@ requires exponent != null;
@ {|
@ requires !isZero() && exponent.equals(ZERO);
@ ensures \result != null && \result.equals(ONE);
@ also
@ forall NaturalNumber v;
@ requires !(exponent.equals(ZERO))
@ && exponent.compareTo(BigInteger.valueOf(Integer.MAX_VALUE))
@ <= 0;
@ ensures v != null && v.suc().equals(exponent)
@ ==> \result != null
@ && \result.equals(this.multiply(this.pow(v)));
@ |}
@ implies_that
@ public normal_behavior
@ requires exponent != null && exponent.equals(ONE);
@ ensures \result != null && \result.equals(this);
@ also
@ public normal_behavior
@ requires exponent != null && this.isZero() && !exponent.isZero()
@ && exponent.compareTo(BigInteger.valueOf(Integer.MAX_VALUE))
@ <= 0;
@ ensures \result != null && \result.equals(ZERO);
@ ensures_redundantly \result != null && \result.equals(this);
@ for_example
@ public normal_example
@ requires exponent != null && exponent.equals(new NaturalNumber(3))
@ && this.equals(new NaturalNumber(3));
@ ensures \result != null && \result.equals(new NaturalNumber(27));
@*/
public /*@ non_null @*/
NaturalNumber pow(/*@ non_null @*/ NaturalNumber exponent)
throws OutOfMemoryError
{
if (exponent.compareTo(intMaxVal) > 0) {
throw new OutOfMemoryError();
} else {
return new NaturalNumber(value.pow(exponent.value.intValue()));//@ nowarn NonNull;
}
} //@ nowarn Exception;
/** The maximum integer as a natural number.
*/
private static final /*@ non_null @*/ NaturalNumber intMaxVal
= new NaturalNumber(Integer.MAX_VALUE);
/** Return this natural number multiplied by itself the given
* number of times.
* @see #multiply
* @see #pow(NaturalNumber)
*/
/*@ public normal_behavior
@ requires exponent >= 0;
@ {|
@ requires !isZero() && exponent == 0;
@ ensures \result != null && \result.equals(ONE);
@ also
@ forall int v;
@ requires exponent != 0;
@ ensures v+1 == exponent
@ ==> \result != null
@ && \result.equals(this.multiply(this.pow(v)));
@ |}
@ implies_that
@ public normal_behavior
@ requires exponent == 1;
@ ensures \result != null && \result.equals(this);
@*/
public /*@ non_null @*/ NaturalNumber pow(int exponent) {
return new NaturalNumber(value.pow(exponent));//@ nowarn NonNull;
} //@ nowarn Exception;
/** Return the greatest common denominator of this number and the
* given number.
*/
/*@ public normal_behavior
@ forall NaturalNumber n;
@ requires !this.isZero() && val != null && !val.isZero();
@ ensures n != null && n.divides(this) && n.divides(val)
@ && (\forall NaturalNumber m;
@ m != null && m.divides(this) && m.divides(val);
@ n.compareTo(m) >= 0)
@ ==> \result.equals(n);
@ also
@ public normal_behavior
@ requires this.isZero() && val != null && val.isZero();
@ ensures \result.isZero();
@ for_example
@ public normal_example
@ requires val != null && val.equals(new NaturalNumber(12))
@ && this.equals(new NaturalNumber(30));
@ ensures \result != null && \result.equals(new NaturalNumber(6));
@*/
public /*@ non_null @*/
NaturalNumber gcd(/*@ non_null @*/ NaturalNumber val)
{
return new NaturalNumber(value.gcd(val.value)); //@ nowarn NonNull;
} //@ nowarn Exception;
// Modular Arithmetic Operations
/** Return this natural number modulo the given one.
* @see #remainder
*/
/*@ public normal_behavior
@ requires m != null && !m.isZero();
@ ensures \result.equals(this.remainder(m));
@ also
@ public exceptional_behavior
@ requires m != null && m.equals(ZERO);
@ signals_only ArithmeticException;
@*/
public /*@ non_null @*/
NaturalNumber mod(/*@ non_null @*/ NaturalNumber m)
{
return new NaturalNumber(value.mod(m.value)); //@ nowarn NonNull;
} //@ nowarn Exception;
// Shift Operations
/** Return this natural number left shifted the given number of bits.
* @see #shiftRight(int)
* @see #pow(int)
*/
/*@ public normal_behavior
@ requires n >= 0;
@ ensures \result != null
@ && \result.equals(this.multiply(
@ new NaturalNumber(2).pow(new NaturalNumber(n))));
@ also
@ public normal_behavior
@ requires n <= 0;
@ ensures \result != null
@ && \result.equals(this.shiftRight(Math.abs(n)));
@ implies_that
@ public normal_behavior
@ requires n == 0;
@ ensures \result != null && \result.equals(this);
@*/
public /*@ non_null @*/ NaturalNumber shiftLeft(int n) {
return new NaturalNumber(value.shiftLeft(n)); //@ nowarn NonNull;
} //@ nowarn Exception;
/** Return this natural number right shifted the given number of bits.
* @see #shiftLeft(int)
* @see #pow(int)
*/
/*@ public normal_behavior
@ requires n >= 0;
@ ensures \result != null
@ && \result.equals(this.divide(
@ new NaturalNumber(2).pow(new NaturalNumber(n))));
@ also
@ public normal_behavior
@ requires n <= 0;
@ ensures \result != null
@ && \result.equals(this.shiftLeft(Math.abs(n)));
@*/
public /*@ non_null @*/ NaturalNumber shiftRight(int n) {
return new NaturalNumber(value.shiftRight(n)); //@ nowarn NonNull;
} //@ nowarn Exception;
// Comparison Operations
/** Return negative if this natural numbers strictly less than the
* given one, 0 if they are equal, and positive if this natural
* numbers is strictly greater than the given one.
* @see #compareTo(Object)
* @see #equals
*/
/*@ public normal_behavior
@ requires val != null;
@ ensures \result
@ == bigIntegerValue().compareTo(val.bigIntegerValue());
@*/
public int compareTo(/*@ non_null @*/ NaturalNumber val) {
return value.compareTo(val.value);
}
/*@ public normal_behavior
@ ensures \result == bigIntegerValue().compareTo(val);
@*/
public int compareTo(/*@ non_null @*/ BigInteger val) {
return value.compareTo(val);
}
/*@ also
@ public normal_behavior
@ requires o != null && o instanceof NaturalNumber;
@ requires this.equals(o);
@ ensures \result == 0;
@*/
public int compareTo(/*@ non_null @*/ Object o)
throws ClassCastException {
return value.compareTo(((NaturalNumber)o).value); //@ nowarn Cast;
}
/** Tell if this object is equal to the given argument.
* @see #compareTo(Object)
* @see #compareTo(NaturalNumber)
* @see #equals
*/
public boolean equals(/*@ nullable @*/ Object x) {
if (x == null || !(x instanceof NaturalNumber)) {
return false;
} else {
return value.equals(((NaturalNumber)x).value);
}
}
public Object clone() {
return this;
}
/** Tell if this object is equal to zero.
* @see #ZERO
* @see #compareTo(NaturalNumber)
* @see #equals
*/
/*@ public normal_behavior
@ ensures \result <==> this.equals(ZERO);
@ ensures_redundantly \result <==> this.compareTo(ZERO) == 0;
@ ensures_redundantly \result <==> this.equals(new NaturalNumber());
@*/
public boolean isZero() {
return value.equals(BigInteger.ZERO);
}
/** Tell if this natural number divides the given one evenly.
* @see #remainder
* @see #mod
*/
/*@ public normal_behavior
@ requires val != null;
@ ensures \result <==> !isZero() && val.remainder(this).equals(ZERO);
@*/
public boolean divides(/*@ non_null @*/ NaturalNumber val) {
return !isZero() && val.remainder(this).equals(ZERO);
}
/** Return the smaller of the given natural number and this one.
* @see #max
* @see #compareTo(NaturalNumber)
*/
/*@ public normal_behavior
@ requires val != null;
@ {|
@ requires this.compareTo(val) <= 0;
@ ensures \result != null && \result.equals(this);
@ also
@ requires val.compareTo(this) <= 0;
@ ensures \result != null && \result.equals(val);
@ |}
@*/
public NaturalNumber min(/*@ non_null @*/ NaturalNumber val) {
return new NaturalNumber(value.min(val.value)); //@ nowarn NonNull;
} //@ nowarn Exception;
/** Return the smaller of the given natural number and this one.
* @see #max
* @see #compareTo(NaturalNumber)
*/
/*@ public normal_behavior
@ requires val != null;
@ {|
@ requires this.compareTo(val) >= 0;
@ ensures \result != null && \result.equals(this);
@ also
@ requires val.compareTo(this) >= 0;
@ ensures \result != null && \result.equals(val);
@ |}
@*/
public NaturalNumber max(/*@ non_null @*/ NaturalNumber val) {
return new NaturalNumber(value.max(val.value)); //@ nowarn NonNull;
} //@ nowarn Exception;
// Hash Function
// inherit specification and documentation comment
public int hashCode() {
return value.hashCode();
}
// inherit specification and documentation comment
public String toString() {
return value.toString();
}
/** Return the BigInteger value of this natural number.
* @see #intValue
* @see #longValue
*/
/*@ public normal_behavior
@ ensures \result != null
@ && new NaturalNumber(\result).equals(this);
@*/
public /*@ non_null @*/ BigInteger bigIntegerValue() {
return value;
}
// overrides of some of Number's methods
// inherit specification and documentation comment
public int intValue() {
return value.intValue();
}
// inherit specification and documentation comment
public long longValue() {
return value.longValue();
}
// inherit specification and documentation comment
public float floatValue() {
return value.floatValue();
}
// inherit specification and documentation comment
public double doubleValue() {
return value.doubleValue();
}
}