3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-02-12 11:54:07 +00:00

Add missing solver APIs to Java and C# bindings (#8464)

* Initial plan

* Add missing solver APIs for Java and C#

- Issue 3: Add getTrailLevels() to Java and TrailLevels property to C#
- Issue 4: Add cube() iterator to Java (C# already had Cube())
- Issue 5: Add setInitialValue() to Java and SetInitialValue() to C#

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Fix code review feedback: eliminate redundant trail retrieval

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

* Improve documentation and efficiency based on code review

Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
Copilot 2026-02-02 09:01:01 -08:00 committed by GitHub
parent 5fa321368c
commit f5a44cf0b9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 122 additions and 0 deletions

View file

@ -390,6 +390,96 @@ public class Solver extends Z3Object {
getNativeObject());
}
/**
* Retrieve the decision levels for each literal in the solver's trail after a {@code check} call.
* The trail contains Boolean literals (decisions and propagations) in the order they were assigned.
* The returned array has one entry per trail literal, indicating at which decision level it was assigned.
* Use {@link #getTrail()} to retrieve the trail literals themselves.
*
* @return An array where element i contains the decision level for the i-th trail literal
* @throws Z3Exception
**/
public int[] getTrailLevels()
{
ASTVector trailVector = new ASTVector(getContext(), Native.solverGetTrail(getContext().nCtx(), getNativeObject()));
int[] levels = new int[trailVector.size()];
Native.solverGetLevels(getContext().nCtx(), getNativeObject(), trailVector.getNativeObject(), trailVector.size(), levels);
return levels;
}
/**
* Return a sequence of cubes (conjunctions of literals) for partitioning the search space.
* Each cube represents a partial assignment that can be used as a starting point for parallel solving.
* This is primarily useful for cube-and-conquer parallel SAT solving strategies, where different
* cubes can be solved independently by different workers.
* The iterator yields cubes until the search space is exhausted.
*
* @param vars Optional array of variables to use as initial cube variables. If null, solver decides.
* @param cutoff Backtrack level cutoff for cube generation
* @return Iterator over arrays of Boolean expressions representing cubes
* @throws Z3Exception
**/
public java.util.Iterator<BoolExpr[]> cube(Expr<?>[] vars, int cutoff)
{
ASTVector cubeVars = new ASTVector(getContext());
if (vars != null) {
for (Expr<?> v : vars) {
cubeVars.push(v);
}
}
return new java.util.Iterator<BoolExpr[]>() {
private BoolExpr[] nextCube = computeNext();
private BoolExpr[] computeNext() {
ASTVector result = new ASTVector(getContext(),
Native.solverCube(getContext().nCtx(), getNativeObject(),
cubeVars.getNativeObject(), cutoff));
BoolExpr[] cube = result.ToBoolExprArray();
// Check for termination conditions
if (cube.length == 1 && cube[0].isFalse()) {
return null; // No more cubes
}
if (cube.length == 0) {
return null; // Search space exhausted
}
return cube;
}
@Override
public boolean hasNext() {
return nextCube != null;
}
@Override
public BoolExpr[] next() {
if (nextCube == null) {
throw new java.util.NoSuchElementException();
}
BoolExpr[] current = nextCube;
nextCube = computeNext();
return current;
}
};
}
/**
* Set an initial value for a variable to guide the solver's search heuristics.
* This can improve performance when good initial values are known for the problem domain.
*
* @param var The variable to set an initial value for
* @param value The initial value for the variable
* @throws Z3Exception
**/
public void setInitialValue(Expr<?> var, Expr<?> value)
{
getContext().checkContextMatch(var);
getContext().checkContextMatch(value);
Native.solverSetInitialValue(getContext().nCtx(), getNativeObject(),
var.getNativeObject(), value.getNativeObject());
}
/**
* Create a clone of the current solver with respect to{@code ctx}.
*/