java-smt icon indicating copy to clipboard operation
java-smt copied to clipboard

MathSAT does not allow variables of different sorts with the same name

Open phantamanta44 opened this issue 3 years ago • 4 comments

MathSAT throws an exception if two variables with the same name and different sorts are ever declared. For example:

SolverContextFactory.createSolverContext(SolverContextFactory.Solvers.MATHSAT5).use { solverCtx ->
    val ifm = solverCtx.formulaManager.integerFormulaManager
    val bfm = solverCtx.formulaManager.booleanFormulaManager
    solverCtx.newProverEnvironment().use { prover ->
        prover.addConstraint(ifm.equal(ifm.makeVariable("x"), ifm.makeNumber(0)))
        println(prover.isUnsat)
    }
    solverCtx.newProverEnvironment().use { prover ->
        prover.addConstraint(bfm.equivalence(bfm.makeVariable("x"), bfm.makeTrue()))
        println(prover.isUnsat)
    }
}

This snippet causes the exception:

Exception in thread "main" java.lang.IllegalArgumentException: A symbol with name `x' already exists, with type: Int
	at org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5NativeApi.msat_declare_function(Native Method)
	at org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5FormulaCreator.makeVariable(Mathsat5FormulaCreator.java:154)
	at org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5FormulaCreator.makeVariable(Mathsat5FormulaCreator.java:137)
	at org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5BooleanFormulaManager.makeVariableImpl(Mathsat5BooleanFormulaManager.java:37)
	at org.sosy_lab.java_smt.solvers.mathsat5.Mathsat5BooleanFormulaManager.makeVariableImpl(Mathsat5BooleanFormulaManager.java:25)
	at org.sosy_lab.java_smt.basicimpl.AbstractBooleanFormulaManager.makeVariable(AbstractBooleanFormulaManager.java:63)
	...

Whereas it works as expected for, e.g. Princess or Z3. I could imagine a solution where Mathsat5Formula is an intermediate representation of the formula that only gets "baked" into a MathSAT native formula when actually making a call to the prover, but that comes with some overhead, of course.

phantamanta44 avatar Jun 30 '22 02:06 phantamanta44

Some solver provide that feature, some do not. Currently, this is expected behavior and we even have tests for that. See https://github.com/sosy-lab/java-smt/blob/0dc452dbd532e414abd08d42ef9b75d504168f77/src/org/sosy_lab/java_smt/test/SolverTheoriesTest.java#L1203 for tests.

Internal renaming of variables is avoided to not confuse the user, when querying models or dumping SMTLIB queries. In the future, we perhaps will add checks to Z3 and Prinzess to not allow identical-named variables any more.

kfriedberger avatar Jun 30 '22 05:06 kfriedberger

So then the idea is that the JavaSMT user should either generate a new solver context for every SMT call, or otherwise implement some kind of unique renaming thing themselves?

phantamanta44 avatar Jun 30 '22 06:06 phantamanta44

yes, separate contexts will help here, or using a naming scheme for different types.

kfriedberger avatar Jul 01 '22 22:07 kfriedberger

Yes. Unique naming on user side is a good idea.

kfriedberger avatar Oct 11 '22 06:10 kfriedberger