diff --git a/liquidjava-verifier/pom.xml b/liquidjava-verifier/pom.xml
index 34ea18db..31d6d166 100644
--- a/liquidjava-verifier/pom.xml
+++ b/liquidjava-verifier/pom.xml
@@ -316,6 +316,11 @@
2.10.1
+
+ info.picocli
+ picocli
+ 4.7.7
+
diff --git a/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineArgs.java b/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineArgs.java
new file mode 100644
index 00000000..9fe7d6d0
--- /dev/null
+++ b/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineArgs.java
@@ -0,0 +1,20 @@
+package liquidjava.api;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+
+import picocli.CommandLine.Command;
+import picocli.CommandLine.Option;
+import picocli.CommandLine.Parameters;
+
+@Command(name = "liquidjava", mixinStandardHelpOptions = false, customSynopsis = "./liquidjava <...paths> ")
+public class CommandLineArgs {
+ @Option(names = {"-h", "--help"}, usageHelp = true, description = "Display this help message")
+ public boolean help;
+
+ @Option(names = { "-d", "--debug" }, description = "Enable debug mode for more detailed output")
+ public boolean debugMode;
+
+ @Parameters(arity = "1..*", paramLabel = "<...paths>", description = "Paths to be verified by LiquidJava")
+ public List paths;
+}
diff --git a/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java b/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java
index e473562c..796928c8 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java
@@ -2,13 +2,13 @@
import java.io.File;
import java.util.Arrays;
-import java.util.List;
import liquidjava.diagnostics.Diagnostics;
import liquidjava.diagnostics.errors.CustomError;
import liquidjava.diagnostics.warnings.CustomWarning;
import liquidjava.processor.RefinementProcessor;
import liquidjava.processor.context.ContextHistory;
+import picocli.CommandLine;
import spoon.Launcher;
import spoon.compiler.Environment;
import spoon.processing.ProcessingManager;
@@ -20,18 +20,18 @@ public class CommandLineLauncher {
private static final Diagnostics diagnostics = Diagnostics.getInstance();
private static final ContextHistory contextHistory = ContextHistory.getInstance();
+ public static final CommandLineArgs cmdArgs = new CommandLineArgs();
public static void main(String[] args) {
- if (args.length == 0) {
- System.out.println("No input paths provided");
- System.out.println("\nUsage: ./liquidjava <...paths>");
- System.out.println(" <...paths>: Paths to be verified by LiquidJava");
- System.out.println(
- "\nExample: ./liquidjava liquidjava-example/src/main/java/test liquidjava-example/src/main/java/testingInProgress/Account.java");
+ CommandLine cmd = new CommandLine(cmdArgs);
+ cmd.parseArgs(args);
+
+ if (cmd.isUsageHelpRequested()) {
+ cmd.usage(System.out);
return;
}
- List paths = Arrays.asList(args);
- launch(paths.toArray(new String[0]));
+
+ launch(cmdArgs.paths.stream().toArray(String[]::new));
// print diagnostics
if (diagnostics.foundWarning()) {
@@ -39,9 +39,10 @@ public static void main(String[] args) {
}
if (diagnostics.foundError()) {
System.out.println(diagnostics.getErrorOutput());
- } else {
- System.out.println("Correct! Passed Verification.");
+ return;
}
+
+ System.out.println("Correct! Passed Verification.");
}
public static void launch(String... paths) {
diff --git a/liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/RefinementError.java b/liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/RefinementError.java
index 380edf9a..9ce59f68 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/RefinementError.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/diagnostics/errors/RefinementError.java
@@ -4,6 +4,7 @@
import java.util.List;
import java.util.stream.Collectors;
+import liquidjava.api.CommandLineLauncher;
import liquidjava.diagnostics.TranslationTable;
import liquidjava.rj_language.opt.derivation_node.ValDerivationNode;
import liquidjava.smt.Counterexample;
@@ -45,7 +46,7 @@ public String getCounterExampleString() {
found.getValue().getVariableNames(foundVarNames);
String counterexampleString = counterexample.assignments().stream()
// only include variables that appear in the found value
- .filter(a -> foundVarNames.contains(a.first()))
+ .filter(a -> CommandLineLauncher.cmdArgs.debugMode || foundVarNames.contains(a.first()))
// format as "var == value"
.map(a -> a.first() + " == " + a.second())
// join with "&&"
diff --git a/liquidjava-verifier/src/main/java/liquidjava/rj_language/Predicate.java b/liquidjava-verifier/src/main/java/liquidjava/rj_language/Predicate.java
index c91380ee..6b6276df 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/rj_language/Predicate.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/rj_language/Predicate.java
@@ -6,6 +6,7 @@
import java.util.Map;
import java.util.stream.Collectors;
+import liquidjava.api.CommandLineLauncher;
import liquidjava.diagnostics.errors.LJError;
import liquidjava.processor.context.AliasWrapper;
import liquidjava.processor.context.Context;
@@ -188,6 +189,9 @@ public Expression getExpression() {
}
public ValDerivationNode simplify() {
+ if (CommandLineLauncher.cmdArgs.debugMode) {
+ return new ValDerivationNode(exp.clone(), null);
+ }
return ExpressionSimplifier.simplify(exp.clone());
}
diff --git a/liquidjava-verifier/src/main/java/liquidjava/rj_language/opt/ExpressionSimplifier.java b/liquidjava-verifier/src/main/java/liquidjava/rj_language/opt/ExpressionSimplifier.java
index 2e43e326..9d2143a9 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/rj_language/opt/ExpressionSimplifier.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/rj_language/opt/ExpressionSimplifier.java
@@ -1,5 +1,6 @@
package liquidjava.rj_language.opt;
+import liquidjava.diagnostics.Diagnostics;
import liquidjava.rj_language.ast.BinaryExpression;
import liquidjava.rj_language.ast.Expression;
import liquidjava.rj_language.ast.LiteralBoolean;
diff --git a/liquidjava-verifier/src/main/java/liquidjava/smt/SMTEvaluator.java b/liquidjava-verifier/src/main/java/liquidjava/smt/SMTEvaluator.java
index 096a9b95..4f7a7537 100644
--- a/liquidjava-verifier/src/main/java/liquidjava/smt/SMTEvaluator.java
+++ b/liquidjava-verifier/src/main/java/liquidjava/smt/SMTEvaluator.java
@@ -1,7 +1,5 @@
package liquidjava.smt;
-import java.util.Set;
-
import com.martiansoftware.jsap.SyntaxException;
import com.microsoft.z3.Expr;
import com.microsoft.z3.Model;
@@ -9,6 +7,7 @@
import com.microsoft.z3.Status;
import com.microsoft.z3.Z3Exception;
+import liquidjava.api.CommandLineLauncher;
import liquidjava.processor.context.Context;
import liquidjava.rj_language.Predicate;
import liquidjava.rj_language.ast.Expression;
@@ -27,6 +26,9 @@ public class SMTEvaluator {
*/
public SMTResult verifySubtype(Predicate subRef, Predicate supRef, Context context) throws Exception {
Predicate toVerify = Predicate.createConjunction(subRef, supRef.negate());
+ if (CommandLineLauncher.cmdArgs.debugMode) {
+ System.out.println(String.format("%s <: %s", subRef, supRef));
+ }
try {
Expression exp = toVerify.getExpression();
try (TranslatorToZ3 tz3 = new TranslatorToZ3(context)) {