Skip to content

Commit 8ed85b5

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 658f654 commit 8ed85b5

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
@@ -74,7 +74,7 @@ public class ProbModelChecker extends NonProbModelChecker
7474
// Parameter for iterative numerical method termination criteria
7575
protected double termCritParam = 1e-8;
7676
// Max iterations for numerical solution
77-
protected int maxIters = 100000;
77+
protected double maxIters = 100000;
7878
// Use precomputation algorithms in model checking?
7979
protected boolean precomp = true;
8080
protected boolean prob0 = true;
@@ -218,7 +218,7 @@ public ProbModelChecker(PrismComponent parent) throws PrismException
218218
// PRISM_TERM_CRIT_PARAM
219219
setTermCritParam(settings.getDouble(PrismSettings.PRISM_TERM_CRIT_PARAM));
220220
// PRISM_MAX_ITERS
221-
setMaxIters(settings.getInteger(PrismSettings.PRISM_MAX_ITERS));
221+
setMaxIters(settings.getDouble(PrismSettings.PRISM_MAX_ITERS));
222222
// PRISM_PRECOMPUTATION
223223
setPrecomp(settings.getBoolean(PrismSettings.PRISM_PRECOMPUTATION));
224224
// PRISM_PROB0
@@ -340,8 +340,9 @@ public void setTermCritParam(double termCritParam)
340340
/**
341341
* Set maximum number of iterations for numerical iterative methods.
342342
*/
343-
public void setMaxIters(int maxIters)
343+
public void setMaxIters(double maxIters)
344344
{
345+
assert maxIters > 0 && maxIters <= Integer.MAX_VALUE && (maxIters == Math.floor(maxIters) || Double.isInfinite(maxIters));
345346
this.maxIters = maxIters;
346347
}
347348

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

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

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
@@ -449,9 +449,12 @@ public void setTermCritParam(double d) throws PrismException
449449
settings.set(PrismSettings.PRISM_TERM_CRIT_PARAM, d);
450450
}
451451

452-
public void setMaxIters(int i) throws PrismException
452+
public void setMaxIters(double d) throws PrismException
453453
{
454-
settings.set(PrismSettings.PRISM_MAX_ITERS, i);
454+
if (! (d > 0 && d <= Integer.MAX_VALUE && (d == Math.floor(d) || Double.isInfinite(d)))) {
455+
throw new PrismException("Expected positive integer or 'Infinity'.");
456+
}
457+
settings.set(PrismSettings.PRISM_MAX_ITERS, d);
455458
}
456459

457460
public void setCUDDMaxMem(String s) throws PrismException
@@ -775,9 +778,9 @@ public double getTermCritParam()
775778
return settings.getDouble(PrismSettings.PRISM_TERM_CRIT_PARAM);
776779
}
777780

778-
public int getMaxIters()
781+
public double getMaxIters()
779782
{
780-
return settings.getInteger(PrismSettings.PRISM_MAX_ITERS);
783+
return settings.getDouble(PrismSettings.PRISM_MAX_ITERS);
781784
}
782785

783786
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
@@ -264,8 +264,8 @@ public class PrismSettings implements Observer
264264
"Criteria to use for checking termination of iterative numerical methods." },
265265
{ DOUBLE_TYPE, PRISM_TERM_CRIT_PARAM, "Termination epsilon", "2.1", new Double(1.0E-6), "0.0,",
266266
"Epsilon value to use for checking termination of iterative numerical methods." },
267-
{ INTEGER_TYPE, PRISM_MAX_ITERS, "Termination max. iterations", "2.1", new Integer(10000), "0,",
268-
"Maximum number of iterations to perform if iterative methods do not converge." },
267+
{ DOUBLE_TYPE, PRISM_MAX_ITERS, "Termination max. iterations", "2.1", Double.valueOf(10000), "0,",
268+
"Maximum number of iterations to perform if iterative methods do not converge. Expects a positive integer of 'Infinity' for unbounded iterations." },
269269
{ BOOLEAN_TYPE, PRISM_EXPORT_ITERATIONS, "Export iterations (debug/visualisation)", "4.3.1", false, "",
270270
"Export solution vectors for iteration algorithms to iterations.html"},
271271
// MODEL CHECKING OPTIONS:
@@ -1162,12 +1162,15 @@ else if (sw.equals("epsilon") || sw.equals("e")) {
11621162
else if (sw.equals("maxiters")) {
11631163
if (i < args.length - 1) {
11641164
try {
1165-
j = Integer.parseInt(args[++i]);
1166-
if (j < 0)
1167-
throw new NumberFormatException("");
1168-
set(PRISM_MAX_ITERS, j);
1165+
double max = Double.parseDouble(args[++i]);
1166+
System.out.println(max);
1167+
System.out.println(Double.isInfinite(max));
1168+
if (! (max > 0 && (max <= Integer.MAX_VALUE && max == Math.floor(max) || Double.isInfinite(max)))) {
1169+
throw new NumberFormatException();
1170+
}
1171+
set(PRISM_MAX_ITERS, max);
11691172
} catch (NumberFormatException e) {
1170-
throw new PrismException("Invalid value for -" + sw + " switch");
1173+
throw new PrismException("Invalid value for -" + sw + " switch. Expected positive integer or 'Infinity'.");
11711174
}
11721175
} else {
11731176
throw new PrismException("No value specified for -" + sw + " switch");
@@ -1813,7 +1816,7 @@ public static void printHelp(PrismLog mainLog)
18131816
mainLog.println("-relative (or -rel) ............ Use relative error for detecting convergence [default]");
18141817
mainLog.println("-absolute (or -abs) ............ Use absolute error for detecting convergence");
18151818
mainLog.println("-epsilon <x> (or -e <x>) ....... Set value of epsilon (for convergence check) [default: 1e-6]");
1816-
mainLog.println("-maxiters <n> .................. Set max number of iterations [default: 10000]");
1819+
mainLog.println("-maxiters <n> .................. Set max number of iterations to positive integer [default: 10000] or 'Infinity' for unbounded interations.");
18171820

18181821
mainLog.println();
18191822
mainLog.println("MODEL CHECKING OPTIONS:");

0 commit comments

Comments
 (0)