Skip to content

Solver independent interpolation#560

Open
juliusbrehme wants to merge 33 commits intomasterfrom
solver_independent_interpolation2_arm64
Open

Solver independent interpolation#560
juliusbrehme wants to merge 33 commits intomasterfrom
solver_independent_interpolation2_arm64

Conversation

@juliusbrehme
Copy link
Collaborator

Implemented independent interpolation strategies to support solvers lacking native interpolation features.

Features added:

  • Uniform Backward/Forward Interpolation.
  • Projection-based Interpolation

baierd and others added 21 commits April 7, 2025 15:36
…of asserted formulas from our tracking of asserted formulas
…dent interpolation (or native) depending on an option when asking for an interpolant (the techniques are unfinished!)
# Conflicts:
#	src/org/sosy_lab/java_smt/test/SolverBasedTest0.java
…rpolatingSolverBasedTest0 and block independent interpolation for tree interpolants properly for now
@juliusbrehme juliusbrehme requested a review from baierd December 20, 2025 17:56
Copy link
Contributor

@baierd baierd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found some minor things to improve, and opened some discussion points about how we want to handle things in general for this extension.

.withMessage(
"Solver %s with strategy %s is not supported or times out",
solverToUse(), itpStrategyToUse())
.that(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to split this assume statement into 2 for clarity.

@Test
public <T> void issue381InterpolationTest2() throws InterruptedException, SolverException {
requireIntegers();
requireSeqItp(itpStrategyToUse());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just override requireSeqItp() in ParameterizedInterpolatingSolverBasedTest0 to always include the strategy for only this class?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this for requireTreeItp as well

public void isValidInterpolant(BooleanFormula interpolant, BooleanFormula a, BooleanFormula b)
throws SolverException, InterruptedException {
// TODO: move into assertion framework
isValidInterpolant(interpolant, ImmutableList.of(a), ImmutableList.of(b));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you look into adding this as an assertion function? Similar to the isUnsatisfiable() method (example: assertThatFormula(query).isUnsatisfiable();)

The new call would then need to interpolate as well of course.

Preconditions.checkState(unsat, "The example for interpolation should be UNSAT");

BooleanFormula itp = prover.getInterpolant(ImmutableList.of(ip1));
logger.log(Level.INFO, "Interpolants are:", itp);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add the interpolation technique used, as well as the interpolant (and the groups A and B if not too large) to the output.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this if the formulas are not longer than 500 chars

import org.sosy_lab.java_smt.api.SolverException;

/** Delegate that wraps non-interpolating provers, allowing them to return itp tracking points. */
public class InterpolatingSolverDelegate extends AbstractProver<String>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we need tests that involve the additional delegates as well, to check for problems when multiple are stacked.

if (interpolationStrategy == null) {
interpolant = delegate.getInterpolant(identifiersForA);

} else if (interpolationStrategy.equals(ProverOptions.GENERATE_PROJECTION_BASED_INTERPOLANTS)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be improved by making it a switch-case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added switch case, but the null can not be in a switch case

}

/** interpolate(A(x,y),B(y,z))=∀z.¬B(y,z). */
private BooleanFormula getUniformBackwardInterpolant(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be beneficial to separate the distinct techniques into their own package and classes, as if we add more techniques, especially techniques with more code, this class will end up very large and hard to read. E.g. a new package package org.sosy_lab.java_smt.basicimpl.interpolation_techniques; with a class for each technique?

* solving over the theories interpolated upon. The solver does not need to support
* interpolation itself.
*/
GENERATE_PROJECTION_BASED_INTERPOLANTS,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kfriedberger @PhilippWendler do you guys have feedback/ideas/proposals for how we want the user to be able to switch in between native and solver independent interpolation techniques? Currently we just ProverOptions, which is not ideal, as they can't be switched once a prover has been created.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would I want to switch the interpolation implementation for a prover instance and why would it be a problem to create a new prover instance instead? I don't really see a use case.

What I am interested in is to have the following 3 possibilities:

  1. create an interpolating prover that guarantees that native solver interpolation is used (and creation fails if this is not possible)
  2. create an interpolating prover that always uses the specific strategy implemented here
  3. create an interpolating prover that prefers the solver native interpolation but falls back to a general implementation if the solver does not support interpolation

The third method could be done by catching the exception from the first case, but why not let JavaSMT provide it as well for the benefit of all its users?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK that seems reasonable.

I thought it might be good to decide about a interpolation technique when asking for interpolants, as users can implement point 3 themselves (potentially even with more than one fallback.

Also interpolation is (usually) only possible after UNSAT has been returned. If a user wants to generate interpolants with multiple techniques in sequence, that would not be possible. E.g.: start with a technique like projection based interpolants that tends to return interpolants fast, but they also tend to be weak -> then use a stronger technique if that first interpolant is not useful. In your approach, a user would need to build a second (or n) new provers and then check satisfiability again.

(Just some thoughts. I want to provide the best possible API. I don't have a preference at the moment.)

@leventeBajczi you also use interpolation, maybe you have some thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really have any further input to this -- as long as it's clear how I'm getting the interpolants, I don't mind if I need to create separate solver instances. We would probably always use point 3 if it was available, especially if it also handled the case when a solver returns an error for the interpolation query (although I'm not sure if the resulting solver state always stays usable). Failing that, we already have some support for using a portfolio of solvers, so we could easily implement the switching ourselves.

* solving over the theories interpolated upon. The solver does not need to support
* interpolation itself.
*/
GENERATE_PROJECTION_BASED_INTERPOLANTS,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might not be a good idea to add options that are only relevant for interpolating provers to the general ProverOptions class? What happens if I create a regular prover environment and tell it to generate interpolants?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added this as a quick dummy. Hence the question about how we want to do it properly ;D

# Conflicts:
#	src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java
#	src/org/sosy_lab/java_smt/test/InterpolatingProverTest.java
…sosy-lab/java-smt into solver_independent_interpolation2_arm64
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants