Skip to content

Commit 5545150

Browse files
Steffen Märckermerkste
authored andcommitted
Implement unbounded iterations #69
The switch -maxiters recognizes a new argument, 'Infinity' to indicate that the number of iteration should not be bounded. If a number is given, it has to be between zero and Integer.MAX_VALUE. The implementation stores these values as doubles. This allows to stick to comparisons like if(iters < max_iters) as +Infinity compares greater to all integer values.
1 parent 42df06d commit 5545150

12 files changed

Lines changed: 53 additions & 45 deletions

prism/include/PrismNativeGlob.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ EXPORT extern int lin_eq_method;
114114
EXPORT extern double lin_eq_method_param;
115115
EXPORT extern int term_crit;
116116
EXPORT extern double term_crit_param;
117-
EXPORT extern int max_iters;
117+
EXPORT extern double max_iters;
118118
// use "compact modified" sparse matrix storage?
119119
EXPORT extern bool compact;
120120
// sparse bits info

prism/include/jni/prism_PrismNative.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

prism/include/jni/sparse_PrismSparse.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

prism/src/explicit/IterationMethod.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,8 +420,8 @@ protected IterationMethod(boolean absolute, double termCritParam)
420420
*/
421421
public ModelCheckerResult doValueIteration(ProbModelChecker mc, String description, IterationValIter iteration, IntSet unknownStates, long startTime, ExportIterations iterationsExport) throws PrismException
422422
{
423+
double maxIters = mc.maxIters;
423424
int iters = 0;
424-
final int maxIters = mc.maxIters;
425425
boolean done = false;
426426

427427
PeriodicTimer updatesTimer = new PeriodicTimer(ProbModelChecker.UPDATE_DELAY);
@@ -484,9 +484,9 @@ public ModelCheckerResult doValueIteration(ProbModelChecker mc, String descripti
484484
public ModelCheckerResult doTopologicalValueIteration(ProbModelChecker mc, String description, SCCInfo sccs, IterationMethod.IterationValIter iterator, SingletonSCCSolver singletonSCCSolver, long startTime, ExportIterations iterationsExport) throws PrismException
485485
{
486486
// Start iterations
487+
double maxIters = mc.maxIters;
487488
int iters = 0;
488489
long mvCount = 0;
489-
final int maxIters = mc.maxIters;
490490
double error = 0.0;
491491

492492
int numSCCs = sccs.getNumSCCs();
@@ -597,8 +597,8 @@ public ModelCheckerResult doTopologicalValueIteration(ProbModelChecker mc, Strin
597597
public ModelCheckerResult doIntervalIteration(ProbModelChecker mc, String description, IterationIntervalIter below, IterationIntervalIter above, IntSet unknownStates, long timer, ExportIterations iterationsExport) throws PrismException {
598598
try {
599599
// Start iterations
600+
double maxIters = mc.maxIters;
600601
int iters = 0;
601-
final int maxIters = mc.maxIters;
602602
boolean done = false;
603603
double maxError = Double.POSITIVE_INFINITY;
604604

@@ -691,9 +691,9 @@ public ModelCheckerResult doIntervalIteration(ProbModelChecker mc, String descri
691691
public ModelCheckerResult doTopologicalIntervalIteration(ProbModelChecker mc, String description, SCCInfo sccs, IterationIntervalIter below, IterationIntervalIter above, SingletonSCCSolver singletonSCCSolver, long timer, ExportIterations iterationsExport) throws PrismException {
692692
try {
693693
// Start iterations
694+
double maxIters = mc.maxIters;
694695
int iters = 0;
695696
long mvCount = 0;
696-
final int maxIters = mc.maxIters;
697697
double maxError = Double.POSITIVE_INFINITY;
698698

699699
PeriodicTimer updatesTimer = new PeriodicTimer(ProbModelChecker.UPDATE_DELAY);

prism/src/explicit/ProbModelChecker.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public class ProbModelChecker extends NonProbModelChecker
7575
// Parameter for iterative numerical method termination criteria
7676
protected double termCritParam = 1e-8;
7777
// Max iterations for numerical solution
78-
protected int maxIters = 100000;
78+
protected double maxIters = 100000.0;
7979
// Resolution for POMDP fixed grid approximation algorithm
8080
protected int gridResolution = 10;
8181
// Use precomputation algorithms in model checking?
@@ -221,7 +221,7 @@ public ProbModelChecker(PrismComponent parent) throws PrismException
221221
// PRISM_TERM_CRIT_PARAM
222222
setTermCritParam(settings.getDouble(PrismSettings.PRISM_TERM_CRIT_PARAM));
223223
// PRISM_MAX_ITERS
224-
setMaxIters(settings.getInteger(PrismSettings.PRISM_MAX_ITERS));
224+
setMaxIters(settings.getDouble(PrismSettings.PRISM_MAX_ITERS));
225225
// PRISM_GRID_RESOLUTION
226226
setGridResolution(settings.getInteger(PrismSettings.PRISM_GRID_RESOLUTION));
227227
// PRISM_PRECOMPUTATION
@@ -347,8 +347,9 @@ public void setTermCritParam(double termCritParam)
347347
/**
348348
* Set maximum number of iterations for numerical iterative methods.
349349
*/
350-
public void setMaxIters(int maxIters)
350+
public void setMaxIters(double maxIters)
351351
{
352+
assert maxIters > 0 && maxIters <= Integer.MAX_VALUE && (maxIters == Math.floor(maxIters) || Double.isInfinite(maxIters));
352353
this.maxIters = maxIters;
353354
}
354355

@@ -453,7 +454,7 @@ public double getTermCritParam()
453454
return termCritParam;
454455
}
455456

456-
public int getMaxIters()
457+
public double getMaxIters()
457458
{
458459
return maxIters;
459460
}

prism/src/prism/MultiObjModelChecker.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -749,11 +749,11 @@ protected TileList generateParetoCurve(NondetModel modelProduct, JDDNode yes_one
749749
{
750750
//TODO this method does not work for more than 2 objectives
751751
int numberOfPoints = 0;
752-
int rewardStepBounds[] = new int[rewards.size()];
752+
double rewardStepBounds[] = new double[rewards.size()];
753753
for (int i = 0; i < rewardStepBounds.length; i++)
754754
rewardStepBounds[i] = opsAndBounds.getRewardStepBound(i);
755755

756-
int probStepBounds[] = new int[targets.length];
756+
double probStepBounds[] = new double[targets.length];
757757
for (int i = 0; i < probStepBounds.length; i++)
758758
probStepBounds[i] = opsAndBounds.getProbStepBound(i);
759759

@@ -1040,11 +1040,11 @@ protected double targetDrivenMultiReachProbs(NondetModel modelProduct, JDDNode y
10401040
List<JDDNode> rewards, OpsAndBoundsList opsAndBounds) throws PrismException
10411041
{
10421042
int numberOfPoints = 0;
1043-
int rewardStepBounds[] = new int[rewards.size()];
1043+
double rewardStepBounds[] = new double[rewards.size()];
10441044
for (int i = 0; i < rewardStepBounds.length; i++)
10451045
rewardStepBounds[i] = opsAndBounds.getRewardStepBound(i);
10461046

1047-
int probStepBounds[] = new int[targets.length];
1047+
double probStepBounds[] = new double[targets.length];
10481048
for (int i = 0; i < probStepBounds.length; i++)
10491049
probStepBounds[i] = opsAndBounds.getProbStepBound(i);
10501050

@@ -1150,7 +1150,7 @@ protected double targetDrivenMultiReachProbs(NondetModel modelProduct, JDDNode y
11501150
//System.out.println("Not doing GS");
11511151
result = PrismSparse.NondetMultiObj(modelProduct.getODD(), modelProduct.getAllDDRowVars(), modelProduct.getAllDDColVars(),
11521152
modelProduct.getAllDDNondetVars(), false, st, adversary, trans_matrix, modelProduct.getSynchs(), null, null,
1153-
new NDSparseMatrix[] { rewSparseMatrices[0] }, new double[] { 1.0 }, new int[] { rewardStepBounds[0] });
1153+
new NDSparseMatrix[] { rewSparseMatrices[0] }, new double[] { 1.0 }, new double[] { rewardStepBounds[0] });
11541154
}
11551155
numberOfPoints++;
11561156

prism/src/prism/Prism.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -454,9 +454,12 @@ public void setTermCritParam(double d) throws PrismException
454454
settings.set(PrismSettings.PRISM_TERM_CRIT_PARAM, d);
455455
}
456456

457-
public void setMaxIters(int i) throws PrismException
457+
public void setMaxIters(double d) throws PrismException
458458
{
459-
settings.set(PrismSettings.PRISM_MAX_ITERS, i);
459+
if (! (d > 0 && d <= Integer.MAX_VALUE && (d == Math.floor(d) || Double.isInfinite(d)))) {
460+
throw new PrismException("Expected positive integer or 'Infinity'.");
461+
}
462+
settings.set(PrismSettings.PRISM_MAX_ITERS, d);
460463
}
461464

462465
public void setGridResolution(int i) throws PrismException
@@ -785,9 +788,9 @@ public double getTermCritParam()
785788
return settings.getDouble(PrismSettings.PRISM_TERM_CRIT_PARAM);
786789
}
787790

788-
public int getMaxIters()
791+
public double getMaxIters()
789792
{
790-
return settings.getInteger(PrismSettings.PRISM_MAX_ITERS);
793+
return settings.getDouble(PrismSettings.PRISM_MAX_ITERS);
791794
}
792795

793796
public int getGridResolution()

prism/src/prism/PrismNative.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ EXPORT int lin_eq_method;
4343
EXPORT double lin_eq_method_param;
4444
EXPORT int term_crit;
4545
EXPORT double term_crit_param;
46-
EXPORT int max_iters;
46+
EXPORT double max_iters;
4747
// use "compact modified" sparse matrix storage?
4848
EXPORT bool compact;
4949
// sparse bits info
@@ -127,9 +127,9 @@ JNIEXPORT void JNICALL Java_prism_PrismNative_PN_1SetTermCritParam(JNIEnv *env,
127127

128128
//------------------------------------------------------------------------------
129129

130-
JNIEXPORT void JNICALL Java_prism_PrismNative_PN_1SetMaxIters(JNIEnv *env, jclass cls, jint i)
130+
JNIEXPORT void JNICALL Java_prism_PrismNative_PN_1SetMaxIters(JNIEnv *env, jclass cls, jdouble d)
131131
{
132-
max_iters = i;
132+
max_iters = d;
133133
}
134134

135135
//------------------------------------------------------------------------------

prism/src/prism/PrismNative.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,11 @@ public static double getTermCritParam()
119119
return termCritParam;
120120
}
121121

122-
private static native void PN_SetMaxIters(int i);
123-
public static void setMaxIters(int i)
122+
private static native void PN_SetMaxIters(double d);
123+
public static void setMaxIters(double d)
124124
{
125-
PN_SetMaxIters(i);
125+
assert d > 0 && d <= Integer.MAX_VALUE && (d == Math.floor(d) || Double.isInfinite(d));
126+
PN_SetMaxIters(d);
126127
}
127128

128129
private static native void PN_SetSBMaxMem(int i);

prism/src/prism/PrismSettings.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -265,8 +265,8 @@ public class PrismSettings implements Observer
265265
"Criteria to use for checking termination of iterative numerical methods." },
266266
{ DOUBLE_TYPE, PRISM_TERM_CRIT_PARAM, "Termination epsilon", "2.1", new Double(1.0E-6), "0.0,",
267267
"Epsilon value to use for checking termination of iterative numerical methods." },
268-
{ INTEGER_TYPE, PRISM_MAX_ITERS, "Termination max. iterations", "2.1", new Integer(10000), "0,",
269-
"Maximum number of iterations to perform if iterative methods do not converge." },
268+
{ DOUBLE_TYPE, PRISM_MAX_ITERS, "Termination max. iterations", "2.1", Double.valueOf(10000), "0,",
269+
"Maximum number of iterations to perform if iterative methods do not converge. Expects a positive integer of 'Infinity' for unbounded iterations." },
270270
{ BOOLEAN_TYPE, PRISM_EXPORT_ITERATIONS, "Export iterations (debug/visualisation)", "4.3.1", false, "",
271271
"Export solution vectors for iteration algorithms to iterations.html"},
272272
{ INTEGER_TYPE, PRISM_GRID_RESOLUTION, "Fixed grid resolution", "4.5", new Integer(10), "1,",
@@ -1165,12 +1165,15 @@ else if (sw.equals("epsilon") || sw.equals("e")) {
11651165
else if (sw.equals("maxiters")) {
11661166
if (i < args.length - 1) {
11671167
try {
1168-
j = Integer.parseInt(args[++i]);
1169-
if (j < 0)
1170-
throw new NumberFormatException("");
1171-
set(PRISM_MAX_ITERS, j);
1168+
double max = Double.parseDouble(args[++i]);
1169+
System.out.println(max);
1170+
System.out.println(Double.isInfinite(max));
1171+
if (! (max > 0 && (max <= Integer.MAX_VALUE && max == Math.floor(max) || Double.isInfinite(max)))) {
1172+
throw new NumberFormatException();
1173+
}
1174+
set(PRISM_MAX_ITERS, max);
11721175
} catch (NumberFormatException e) {
1173-
throw new PrismException("Invalid value for -" + sw + " switch");
1176+
throw new PrismException("Invalid value for -" + sw + " switch. Expected positive integer or 'Infinity'.");
11741177
}
11751178
} else {
11761179
throw new PrismException("No value specified for -" + sw + " switch");
@@ -1831,9 +1834,9 @@ public static void printHelp(PrismLog mainLog)
18311834
mainLog.println("-relative (or -rel) ............ Use relative error for detecting convergence [default]");
18321835
mainLog.println("-absolute (or -abs) ............ Use absolute error for detecting convergence");
18331836
mainLog.println("-epsilon <x> (or -e <x>) ....... Set value of epsilon (for convergence check) [default: 1e-6]");
1834-
mainLog.println("-maxiters <n> .................. Set max number of iterations [default: 10000]");
1837+
mainLog.println("-maxiters <n> .................. Set max number of iterations to positive integer [default: 10000] or 'Infinity' for unbounded interations.");
18351838
mainLog.println("-gridresolution <n> .............Set resolution for fixed grid approximation (POMDP) [default: 10]");
1836-
1839+
18371840
mainLog.println();
18381841
mainLog.println("MODEL CHECKING OPTIONS:");
18391842
mainLog.println("-nopre ......................... Skip precomputation algorithms (where optional)");

0 commit comments

Comments
 (0)