Skip to content

Commit d6c2116

Browse files
author
Steffen Märcker
committed
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 ed62b2c commit d6c2116

12 files changed

Lines changed: 52 additions & 44 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
@@ -401,8 +401,8 @@ protected IterationMethod(boolean absolute, double termCritParam)
401401
*/
402402
public ModelCheckerResult doValueIteration(ProbModelChecker mc, String description, IterationValIter iteration, IntSet unknownStates, long startTime, ExportIterations iterationsExport) throws PrismException
403403
{
404+
double maxIters = mc.maxIters;
404405
int iters = 0;
405-
final int maxIters = mc.maxIters;
406406
boolean done = false;
407407

408408
PeriodicTimer updatesTimer = new PeriodicTimer(ProbModelChecker.UPDATE_DELAY);
@@ -464,9 +464,9 @@ public ModelCheckerResult doValueIteration(ProbModelChecker mc, String descripti
464464
public ModelCheckerResult doTopologicalValueIteration(ProbModelChecker mc, String description, SCCInfo sccs, IterationMethod.IterationValIter iterator, SingletonSCCSolver singletonSCCSolver, long startTime, ExportIterations iterationsExport) throws PrismException
465465
{
466466
// Start iterations
467+
double maxIters = mc.maxIters;
467468
int iters = 0;
468469
long mvCount = 0;
469-
final int maxIters = mc.maxIters;
470470

471471
int numSCCs = sccs.getNumSCCs();
472472
int numNonSingletonSCCs = sccs.countNonSingletonSCCs();
@@ -572,8 +572,8 @@ public ModelCheckerResult doTopologicalValueIteration(ProbModelChecker mc, Strin
572572
public ModelCheckerResult doIntervalIteration(ProbModelChecker mc, String description, IterationIntervalIter below, IterationIntervalIter above, IntSet unknownStates, long timer, ExportIterations iterationsExport) throws PrismException {
573573
try {
574574
// Start iterations
575+
double maxIters = mc.maxIters;
575576
int iters = 0;
576-
final int maxIters = mc.maxIters;
577577
boolean done = false;
578578

579579
PeriodicTimer updatesTimer = new PeriodicTimer(ProbModelChecker.UPDATE_DELAY);
@@ -664,9 +664,9 @@ public ModelCheckerResult doIntervalIteration(ProbModelChecker mc, String descri
664664
public ModelCheckerResult doTopologicalIntervalIteration(ProbModelChecker mc, String description, SCCInfo sccs, IterationIntervalIter below, IterationIntervalIter above, SingletonSCCSolver singletonSCCSolver, long timer, ExportIterations iterationsExport) throws PrismException {
665665
try {
666666
// Start iterations
667+
double maxIters = mc.maxIters;
667668
int iters = 0;
668669
long mvCount = 0;
669-
final int maxIters = mc.maxIters;
670670

671671
PeriodicTimer updatesTimer = new PeriodicTimer(ProbModelChecker.UPDATE_DELAY);
672672
updatesTimer.start();

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;
7979
// Use precomputation algorithms in model checking?
8080
protected boolean precomp = true;
8181
protected boolean prob0 = true;
@@ -219,7 +219,7 @@ public ProbModelChecker(PrismComponent parent) throws PrismException
219219
// PRISM_TERM_CRIT_PARAM
220220
setTermCritParam(settings.getDouble(PrismSettings.PRISM_TERM_CRIT_PARAM));
221221
// PRISM_MAX_ITERS
222-
setMaxIters(settings.getInteger(PrismSettings.PRISM_MAX_ITERS));
222+
setMaxIters(settings.getDouble(PrismSettings.PRISM_MAX_ITERS));
223223
// PRISM_PRECOMPUTATION
224224
setPrecomp(settings.getBoolean(PrismSettings.PRISM_PRECOMPUTATION));
225225
// PRISM_PROB0
@@ -341,8 +341,9 @@ public void setTermCritParam(double termCritParam)
341341
/**
342342
* Set maximum number of iterations for numerical iterative methods.
343343
*/
344-
public void setMaxIters(int maxIters)
344+
public void setMaxIters(double maxIters)
345345
{
346+
assert maxIters > 0 && maxIters <= Integer.MAX_VALUE && (maxIters == Math.floor(maxIters) || Double.isInfinite(maxIters));
346347
this.maxIters = maxIters;
347348
}
348349

@@ -439,7 +440,7 @@ public double getTermCritParam()
439440
return termCritParam;
440441
}
441442

442-
public int getMaxIters()
443+
public double getMaxIters()
443444
{
444445
return maxIters;
445446
}

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

@@ -1035,11 +1035,11 @@ protected double targetDrivenMultiReachProbs(NondetModel modelProduct, JDDNode y
10351035
List<JDDNode> rewards, OpsAndBoundsList opsAndBounds) throws PrismException
10361036
{
10371037
int numberOfPoints = 0;
1038-
int rewardStepBounds[] = new int[rewards.size()];
1038+
double rewardStepBounds[] = new double[rewards.size()];
10391039
for (int i = 0; i < rewardStepBounds.length; i++)
10401040
rewardStepBounds[i] = opsAndBounds.getRewardStepBound(i);
10411041

1042-
int probStepBounds[] = new int[targets.length];
1042+
double probStepBounds[] = new double[targets.length];
10431043
for (int i = 0; i < probStepBounds.length; i++)
10441044
probStepBounds[i] = opsAndBounds.getProbStepBound(i);
10451045

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

prism/src/prism/Prism.java

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

447-
public void setMaxIters(int i) throws PrismException
447+
public void setMaxIters(double d) throws PrismException
448448
{
449-
settings.set(PrismSettings.PRISM_MAX_ITERS, i);
449+
if (! (d > 0 && d <= Integer.MAX_VALUE && (d == Math.floor(d) || Double.isInfinite(d)))) {
450+
throw new PrismException("Expected positive integer or 'Infinity'.");
451+
}
452+
settings.set(PrismSettings.PRISM_MAX_ITERS, d);
450453
}
451454

452455
public void setCUDDMaxMem(String s) throws PrismException
@@ -770,9 +773,9 @@ public double getTermCritParam()
770773
return settings.getDouble(PrismSettings.PRISM_TERM_CRIT_PARAM);
771774
}
772775

773-
public int getMaxIters()
776+
public double getMaxIters()
774777
{
775-
return settings.getInteger(PrismSettings.PRISM_MAX_ITERS);
778+
return settings.getDouble(PrismSettings.PRISM_MAX_ITERS);
776779
}
777780

778781
public boolean getVerbose()

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
@@ -124,9 +124,9 @@ JNIEXPORT void JNICALL Java_prism_PrismNative_PN_1SetTermCritParam(JNIEnv *env,
124124

125125
//------------------------------------------------------------------------------
126126

127-
JNIEXPORT void JNICALL Java_prism_PrismNative_PN_1SetMaxIters(JNIEnv *env, jclass cls, jint i)
127+
JNIEXPORT void JNICALL Java_prism_PrismNative_PN_1SetMaxIters(JNIEnv *env, jclass cls, jdouble d)
128128
{
129-
max_iters = i;
129+
max_iters = d;
130130
}
131131

132132
//------------------------------------------------------------------------------

prism/src/prism/PrismNative.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,11 @@ public static void setTermCritParam(double d)
105105
PN_SetTermCritParam(d);
106106
}
107107

108-
private static native void PN_SetMaxIters(int i);
109-
public static void setMaxIters(int i)
108+
private static native void PN_SetMaxIters(double d);
109+
public static void setMaxIters(double d)
110110
{
111-
PN_SetMaxIters(i);
111+
assert d > 0 && d <= Integer.MAX_VALUE && (d == Math.floor(d) || Double.isInfinite(d));
112+
PN_SetMaxIters(d);
112113
}
113114

114115
private static native void PN_SetSBMaxMem(int i);

prism/src/prism/PrismSettings.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ public class PrismSettings implements Observer
261261
"Criteria to use for checking termination of iterative numerical methods." },
262262
{ DOUBLE_TYPE, PRISM_TERM_CRIT_PARAM, "Termination epsilon", "2.1", new Double(1.0E-6), "0.0,",
263263
"Epsilon value to use for checking termination of iterative numerical methods." },
264-
{ INTEGER_TYPE, PRISM_MAX_ITERS, "Termination max. iterations", "2.1", new Integer(10000), "0,",
265-
"Maximum number of iterations to perform if iterative methods do not converge." },
264+
{ DOUBLE_TYPE, PRISM_MAX_ITERS, "Termination max. iterations", "2.1", Double.valueOf(10000), "0,",
265+
"Maximum number of iterations to perform if iterative methods do not converge. Expects a positive integer of 'Infinity' for unbounded iterations." },
266266
{ BOOLEAN_TYPE, PRISM_EXPORT_ITERATIONS, "Export iterations (debug/visualisation)", "4.3.1", false, "",
267267
"Export solution vectors for iteration algorithms to iterations.html"},
268268
// MODEL CHECKING OPTIONS:
@@ -1143,12 +1143,15 @@ else if (sw.equals("epsilon") || sw.equals("e")) {
11431143
else if (sw.equals("maxiters")) {
11441144
if (i < args.length - 1) {
11451145
try {
1146-
j = Integer.parseInt(args[++i]);
1147-
if (j < 0)
1148-
throw new NumberFormatException("");
1149-
set(PRISM_MAX_ITERS, j);
1146+
double max = Double.parseDouble(args[++i]);
1147+
System.out.println(max);
1148+
System.out.println(Double.isInfinite(max));
1149+
if (! (max > 0 && (max <= Integer.MAX_VALUE && max == Math.floor(max) || Double.isInfinite(max)))) {
1150+
throw new NumberFormatException();
1151+
}
1152+
set(PRISM_MAX_ITERS, max);
11501153
} catch (NumberFormatException e) {
1151-
throw new PrismException("Invalid value for -" + sw + " switch");
1154+
throw new PrismException("Invalid value for -" + sw + " switch. Expected positive integer or 'Infinity'.");
11521155
}
11531156
} else {
11541157
throw new PrismException("No value specified for -" + sw + " switch");
@@ -1793,7 +1796,7 @@ public static void printHelp(PrismLog mainLog)
17931796
mainLog.println("-relative (or -rel) ............ Use relative error for detecting convergence [default]");
17941797
mainLog.println("-absolute (or -abs) ............ Use absolute error for detecting convergence");
17951798
mainLog.println("-epsilon <x> (or -e <x>) ....... Set value of epsilon (for convergence check) [default: 1e-6]");
1796-
mainLog.println("-maxiters <n> .................. Set max number of iterations [default: 10000]");
1799+
mainLog.println("-maxiters <n> .................. Set max number of iterations to positive integer [default: 10000] or 'Infinity' for unbounded interations.");
17971800

17981801
mainLog.println();
17991802
mainLog.println("MODEL CHECKING OPTIONS:");

0 commit comments

Comments
 (0)