Skip to content

Commit 5c61500

Browse files
committed
#389: add ConfigurationOption to give CVC5 some options directly.
1 parent bf6bda3 commit 5c61500

File tree

2 files changed

+74
-5
lines changed

2 files changed

+74
-5
lines changed

src/org/sosy_lab/java_smt/solvers/cvc5/CVC5SolverContext.java

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,20 @@
22
// an API wrapper for a collection of SMT solvers:
33
// https://github.com/sosy-lab/java-smt
44
//
5-
// SPDX-FileCopyrightText: 2022 Dirk Beyer <https://www.sosy-lab.org>
5+
// SPDX-FileCopyrightText: 2024 Dirk Beyer <https://www.sosy-lab.org>
66
//
77
// SPDX-License-Identifier: Apache-2.0
88

99
package org.sosy_lab.java_smt.solvers.cvc5;
1010

1111
import com.google.common.annotations.VisibleForTesting;
1212
import com.google.common.base.Preconditions;
13+
import com.google.common.base.Splitter;
14+
import com.google.common.base.Splitter.MapSplitter;
15+
import com.google.common.collect.ImmutableMap;
16+
import io.github.cvc5.CVC5ApiRecoverableException;
1317
import io.github.cvc5.Solver;
18+
import java.util.Map.Entry;
1419
import java.util.Set;
1520
import java.util.function.Consumer;
1621
import org.sosy_lab.common.ShutdownNotifier;
@@ -38,8 +43,30 @@ private static class CVC5Settings {
3843
description = "apply additional validation checks for interpolation results")
3944
private boolean validateInterpolants = false;
4045

46+
@Option(
47+
secure = true,
48+
description =
49+
"Further options that will be passed to CVC5 in addition to the default options. "
50+
+ "Format is 'key1=value1,key2=value2'")
51+
private String furtherOptions = "";
52+
53+
private final ImmutableMap<String, String> furtherOptionsMap;
54+
4155
private CVC5Settings(Configuration config) throws InvalidConfigurationException {
4256
config.inject(this);
57+
58+
MapSplitter optionSplitter =
59+
Splitter.on(',')
60+
.trimResults()
61+
.omitEmptyStrings()
62+
.withKeyValueSeparator(Splitter.on('=').limit(2).trimResults());
63+
64+
try {
65+
furtherOptionsMap = ImmutableMap.copyOf(optionSplitter.split(furtherOptions));
66+
} catch (IllegalArgumentException e) {
67+
throw new InvalidConfigurationException(
68+
"Invalid CVC5 option in \"" + furtherOptions + "\": " + e.getMessage(), e);
69+
}
4370
}
4471
}
4572

@@ -94,7 +121,11 @@ public static SolverContext create(
94121
// We keep this instance available until the whole context is closed.
95122
Solver newSolver = new Solver();
96123

97-
setSolverOptions(newSolver, randomSeed);
124+
try {
125+
setSolverOptions(newSolver, randomSeed, settings.furtherOptionsMap);
126+
} catch (CVC5ApiRecoverableException e) { // we do not want to recover after invalid options.
127+
throw new InvalidConfigurationException(e.getMessage(), e);
128+
}
98129

99130
CVC5FormulaCreator pCreator = new CVC5FormulaCreator(newSolver);
100131

@@ -133,11 +164,21 @@ public static SolverContext create(
133164
pCreator, manager, pShutdownNotifier, newSolver, randomSeed, settings);
134165
}
135166

136-
/** Set common options for a CVC5 solver. */
137-
private static void setSolverOptions(Solver pSolver, int randomSeed) {
167+
/**
168+
* Set common options for a CVC5 solver.
169+
*
170+
* @throws CVC5ApiRecoverableException from native code.
171+
*/
172+
private static void setSolverOptions(
173+
Solver pSolver, int randomSeed, ImmutableMap<String, String> furtherOptions)
174+
throws CVC5ApiRecoverableException {
138175
pSolver.setOption("seed", String.valueOf(randomSeed));
139176
pSolver.setOption("output-language", "smtlib2");
140177

178+
for (Entry<String, String> option : furtherOptions.entrySet()) {
179+
pSolver.setOption(option.getKey(), option.getValue());
180+
}
181+
141182
// Set Strings option to enable all String features (such as lessOrEquals).
142183
// This should not have any effect for non-string theories.
143184
// pSolver.setOption("strings-exp", "true");

src/org/sosy_lab/java_smt/test/SolverContextTest.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
// an API wrapper for a collection of SMT solvers:
33
// https://github.com/sosy-lab/java-smt
44
//
5-
// SPDX-FileCopyrightText: 2020 Dirk Beyer <https://www.sosy-lab.org>
5+
// SPDX-FileCopyrightText: 2024 Dirk Beyer <https://www.sosy-lab.org>
66
//
77
// SPDX-License-Identifier: Apache-2.0
88

99
package org.sosy_lab.java_smt.test;
1010

1111
import static com.google.common.truth.Truth.assertThat;
1212
import static com.google.common.truth.TruthJUnit.assume;
13+
import static org.junit.Assert.assertThrows;
1314

1415
import org.junit.Test;
16+
import org.sosy_lab.common.configuration.InvalidConfigurationException;
17+
import org.sosy_lab.java_smt.SolverContextFactory;
1518
import org.sosy_lab.java_smt.SolverContextFactory.Solvers;
1619
import org.sosy_lab.java_smt.api.BooleanFormula;
1720

@@ -120,4 +123,29 @@ public void testFormulaAccessAfterClose() {
120123
assertThat(bmgr.isTrue(opTerm)).isFalse();
121124
assertThat(bmgr.isFalse(opTerm)).isFalse();
122125
}
126+
127+
@Test
128+
@SuppressWarnings("try")
129+
public void testCVC5WithValidOptions() throws InvalidConfigurationException {
130+
assume().that(solverToUse()).isEqualTo(Solvers.CVC5);
131+
132+
var config =
133+
createTestConfigBuilder()
134+
.setOption("solver.cvc5.furtherOptions", "solve-bv-as-int=bitwise")
135+
.build();
136+
var factory = new SolverContextFactory(config, logger, shutdownNotifierToUse());
137+
try (var context = factory.generateContext()) {
138+
// create and ignore
139+
}
140+
}
141+
142+
@Test
143+
public void testCVC5WithInvalidOptions() throws InvalidConfigurationException {
144+
assume().that(solverToUse()).isEqualTo(Solvers.CVC5);
145+
146+
var config =
147+
createTestConfigBuilder().setOption("solver.cvc5.furtherOptions", "foo=bar").build();
148+
var factory = new SolverContextFactory(config, logger, shutdownNotifierToUse());
149+
assertThrows(InvalidConfigurationException.class, factory::generateContext);
150+
}
123151
}

0 commit comments

Comments
 (0)