diff --git a/quickcheck/src/main/java/quickcheck/QuickCheck.java b/quickcheck/src/main/java/quickcheck/QuickCheck.java
index 91833dc5e..dd8c529d7 100644
--- a/quickcheck/src/main/java/quickcheck/QuickCheck.java
+++ b/quickcheck/src/main/java/quickcheck/QuickCheck.java
@@ -73,6 +73,7 @@
import quickcheck.strategies.QCStrategy;
import quickcheck.strategies.StrategyResults;
import quickcheck.visitors.FixedRangeCreator;
+import quickcheck.visitors.MaybeFinder;
import quickcheck.visitors.TypeBindFinder;
public class QuickCheck
@@ -399,7 +400,7 @@ else if (results.provedBy != null)
if (values != null)
{
verbose("PO #%d, setting %s, %d values\n", po.number, mbind.toString(), values.size());
- mbind.setBindValues(values, timeout);
+ mbind.setBindValues(values, timeout, results.hasAllValues);
}
else
{
@@ -428,6 +429,7 @@ else if (results.provedBy != null)
Value execResult = new BooleanValue(false);
ContextException execException = null;
boolean execCompleted = false;
+ boolean hasMaybe = false;
long before = System.currentTimeMillis();
try
@@ -442,6 +444,10 @@ else if (results.provedBy != null)
{
ictxt.next();
execResult = poexp.eval(ictxt);
+
+ MaybeFinder finder = new MaybeFinder();
+ poexp.apply(finder, null);
+ hasMaybe = finder.hasMaybe();
}
while (ictxt.hasNext() && execResult.boolValue(ctxt));
@@ -502,6 +508,10 @@ else if (execResult instanceof BooleanValue)
{
outcome = POStatus.TIMEOUT;
}
+ else if (hasMaybe)
+ {
+ outcome = POStatus.MAYBE;
+ }
else if (po.isExistential())
{
outcome = POStatus.PROVED; // An "exists" PO is PROVED, if true.
@@ -540,6 +550,14 @@ else if (results.hasAllValues && execCompleted)
po.setMessage(null);
po.setWitness(null);
}
+ else if (hasMaybe)
+ {
+ infof(POStatus.MAYBE, "PO #%d, MAYBE %s\n", po.number, duration(before, after));
+ po.setStatus(POStatus.MAYBE);
+ po.setCounterexample(null);
+ po.setMessage(null);
+ po.setWitness(null);
+ }
else if (po.isExistential()) // Principal exp is "exists..."
{
if (results.hasAllValues)
@@ -615,7 +633,7 @@ else if (po.isExistential()) // Principal exp is "exists..."
{
for (INBindingSetter mbind: bindings)
{
- mbind.setBindValues(null, 0); // Clears everything
+ mbind.setBindValues(null, 0, false); // Clears everything
}
}
}
diff --git a/quickcheck/src/main/java/quickcheck/strategies/SearchQCStrategy.java b/quickcheck/src/main/java/quickcheck/strategies/SearchQCStrategy.java
index a4eb814b0..054965c7e 100644
--- a/quickcheck/src/main/java/quickcheck/strategies/SearchQCStrategy.java
+++ b/quickcheck/src/main/java/quickcheck/strategies/SearchQCStrategy.java
@@ -90,7 +90,7 @@ public StrategyResults getValues(ProofObligation po, INExpression exp, List.
+ * SPDX-License-Identifier: GPL-3.0-or-later
+ *
+ ******************************************************************************/
+package quickcheck.visitors;
+
+import java.util.List;
+import java.util.Vector;
+
+import com.fujitsu.vdmj.in.expressions.INExistsExpression;
+import com.fujitsu.vdmj.in.expressions.INExpression;
+import com.fujitsu.vdmj.in.expressions.INForAllExpression;
+import com.fujitsu.vdmj.in.expressions.visitors.INLeafExpressionVisitor;
+
+/**
+ * Search an expression tree after a QuickCheck execution to decide the outcome.
+ * This is affected by the forall/exists subexpressions, whether they have
+ * type bindings set and whether the binds have all type values.
+ */
+public class MaybeFinder extends INLeafExpressionVisitor