@ -27,6 +27,7 @@
package prism ;
import param.BigRational ;
import parser.type.* ;
/ * *
@ -80,14 +81,22 @@ public class DefinedConstant
return ( low ! = null ) ;
}
/** Define the constant (by passing in strings). */
public void define ( String sl , String sh , String ss ) throws PrismException
/ * *
* Define the constant ( by passing in strings ) .
* < br >
* If { @code exact } is true , BigRationals are used for real values ,
* otherwise double arithmetic is used .
* /
public void define ( String sl , String sh , String ss , boolean exact ) throws PrismException
{
if ( type instanceof TypeInt ) {
defineInt ( sl , sh , ss ) ;
} else if ( type instanceof TypeDouble ) {
defineDouble ( sl , sh , ss ) ;
} else if ( type instanceof TypeDouble ) {
if ( exact ) {
defineBigRational ( sl , sh , ss ) ;
} else {
defineDouble ( sl , sh , ss ) ;
}
} else if ( type instanceof TypeBool ) {
defineBoolean ( sl , sh , ss ) ;
} else {
@ -212,7 +221,65 @@ public class DefinedConstant
high = new Double ( dh ) ;
step = new Double ( ds ) ;
}
public void defineBigRational ( String sl , String sh , String ss ) throws PrismException
{
BigRational r , rl , rh , rs ;
/ / parse low value
try {
rl = BigRational . from ( sl ) ;
}
catch ( NumberFormatException e ) {
throw new PrismException ( "Value " + sl + " for constant " + name + " is not a valid rational number" ) ;
}
/ / if no high value given , use low value , default step is 1 . 0
if ( sh = = null ) {
rh = rl ;
rs = BigRational . from ( 1 ) ;
}
else {
/ / parse high value
try {
rh = BigRational . from ( sh ) ;
}
catch ( NumberFormatException e ) {
throw new PrismException ( "Value " + sh + " for constant " + name + " is not a valid rational number" ) ;
}
if ( rh . lessThan ( rl ) ) throw new PrismException ( "Low value " + rl + " for constant " + name + " is higher than the high value " + rh ) ;
if ( ss = = null ) {
/ / default step is 1 . 0
rs = BigRational . from ( 1 ) ;
}
else {
/ / parse step
try {
rs = BigRational . from ( ss ) ;
}
catch ( NumberFormatException e ) {
throw new PrismException ( "Value " + ss + " for constant " + name + " is not a valid double" ) ;
}
if ( rs . isZero ( ) ) throw new PrismException ( "Step value for constant " + name + " cannot be zero" ) ;
if ( rs . lessThan ( BigRational . ZERO ) ) throw new PrismException ( "Step value for constant " + name + " must be positive" ) ;
if ( rs . greaterThan ( rh . subtract ( rl ) ) ) throw new PrismException ( "Step value " + rs + " for constant " + name + " is bigger than the difference between " + rl + " and " + rh ) ;
}
}
/ / compute num steps
numSteps = 0 ;
BigRational rhNew = rh ;
for ( r = rl ; r . lessThanEquals ( rh ) ; r = rl . add ( rs . multiply ( numSteps ) ) )
{
numSteps + + ;
rhNew = r ;
}
/ / store ' actual ' value for high
rh = rhNew ;
/ / store
low = rl ;
high = rh ;
step = rs ;
}
public void defineBoolean ( String sl , String sh , String ss ) throws PrismException
{
/ / parse value ( low )
@ -261,20 +328,39 @@ public class DefinedConstant
}
/ / double
else if ( type instanceof TypeDouble ) {
dl = ( ( Double ) low ) . doubleValue ( ) ;
dh = ( ( Double ) high ) . doubleValue ( ) ;
ds = ( ( Double ) step ) . doubleValue ( ) ;
dv = ( ( Double ) value ) . doubleValue ( ) ;
/ / if possible , increment
int index = getValueIndex ( value ) + 1 ;
dv = dl + index * ds ;
if ( dv < = dh + DOUBLE_PRECISION_CORRECTION * ds ) {
value = new Double ( dv ) ;
}
/ / otherwise , reset to low value , note overflow
else {
value = low ;
overflow = true ;
if ( low instanceof BigRational ) {
BigRational rl = ( BigRational ) low ;
BigRational rh = ( BigRational ) high ;
BigRational rs = ( BigRational ) step ;
BigRational rv = ( BigRational ) value ;
/ / if possible , increment
int index = getValueIndex ( value ) + 1 ;
rv = rl . add ( rs . multiply ( index ) ) ;
if ( rv . lessThanEquals ( rh ) ) {
value = rv ;
}
/ / otherwise , reset to low value , note overflow
else {
value = low ;
overflow = true ;
}
} else {
/ / double arithmetic
dl = ( ( Double ) low ) . doubleValue ( ) ;
dh = ( ( Double ) high ) . doubleValue ( ) ;
ds = ( ( Double ) step ) . doubleValue ( ) ;
dv = ( ( Double ) value ) . doubleValue ( ) ;
/ / if possible , increment
int index = getValueIndex ( value ) + 1 ;
dv = dl + index * ds ;
if ( dv < = dh + DOUBLE_PRECISION_CORRECTION * ds ) {
value = new Double ( dv ) ;
}
/ / otherwise , reset to low value , note overflow
else {
value = low ;
overflow = true ;
}
}
}
/ / boolean
@ -315,12 +401,21 @@ public class DefinedConstant
}
/ / double
else if ( type instanceof TypeDouble ) {
dl = ( ( Double ) low ) . doubleValue ( ) ;
ds = ( ( Double ) step ) . doubleValue ( ) ;
dv = dl ;
/ / for ( i = 0 ; i < j ; i + + ) dv + = ds ;
dv = dl + j * ds ;
return new Double ( dv ) ;
if ( low instanceof BigRational ) {
BigRational rl = ( BigRational ) low ;
BigRational rs = ( BigRational ) low ;
BigRational rv ;
/ / rv = rl + j * rs
rv = rl . add ( rs . multiply ( j ) ) ;
return rv ;
} else {
dl = ( ( Double ) low ) . doubleValue ( ) ;
ds = ( ( Double ) step ) . doubleValue ( ) ;
dv = dl ;
/ / for ( i = 0 ; i < j ; i + + ) dv + = ds ;
dv = dl + j * ds ;
return new Double ( dv ) ;
}
}
/ / boolean ( case should be redundant )
else if ( type instanceof TypeBool ) {
@ -350,10 +445,22 @@ public class DefinedConstant
}
/ / double
else if ( type instanceof TypeDouble ) {
dl = ( ( Double ) low ) . doubleValue ( ) ;
ds = ( ( Double ) step ) . doubleValue ( ) ;
dv = ( ( Double ) v ) . doubleValue ( ) ;
return ( int ) Math . round ( ( dv - dl ) / ds ) ;
if ( low instanceof BigRational ) {
BigRational rl = ( BigRational ) low ;
BigRational rs = ( BigRational ) step ;
BigRational rv = ( BigRational ) value ;
BigRational index = ( rv . subtract ( rl ) ) . divide ( rs ) ;
try {
return index . toInt ( ) ;
} catch ( PrismLangException e ) {
throw new IllegalArgumentException ( "Can not compute value index, out of range: " + e ) ;
}
} else {
dl = ( ( Double ) low ) . doubleValue ( ) ;
ds = ( ( Double ) step ) . doubleValue ( ) ;
dv = ( ( Double ) v ) . doubleValue ( ) ;
return ( int ) Math . round ( ( dv - dl ) / ds ) ;
}
}
/ / boolean ( case should be redundant )
else if ( type instanceof TypeBool ) {