Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Formula with same string representation compares as unequal #315

Open
PhilippWendler opened this issue Jun 22, 2023 · 5 comments
Open

Formula with same string representation compares as unequal #315

PhilippWendler opened this issue Jun 22, 2023 · 5 comments
Assignees
Labels

Comments

@PhilippWendler
Copy link
Member

The following test fails with Z3:

    BooleanFormula var1 = bmgr.makeVariable("var1");
    BooleanFormula var2 = bmgr.makeVariable("var2");
    BooleanFormula var3 = bmgr.makeVariable("var3");
    BooleanFormula var4 = bmgr.makeVariable("var4");
    assertThat(bmgr.and(bmgr.and(var1, var2), bmgr.and(var3, var4)))
        .isEqualTo(bmgr.and(var1, var2, var3, var4));

(It also fails with some other solvers because JavaSMT is missing simplifications, but this is a different issue.)

The problem with Z3 is that both bmgr.and(bmgr.and(var1, var2), bmgr.and(var3, var4)) and bmgr.and(var1, var2, var3, var4) create the same formula, specifically (and var1 var2 var3 var4), but that equals() on these two instances returns false. Objects representing the same syntactic formula should compare as equal.

(This even works in other cases. If I call bmgr.and(bmgr.and(var1, var2), bmgr.and(var3, var4)) twice, I do get formula instances that compare as equal, just in the above case not.)

@baierd
Copy link
Collaborator

baierd commented Jun 22, 2023

On a broader note: we should have tests for this and some other basic cases.
@RSoegtrop can you take a look at this issue and add some tests that cover this and some other basic cases?

@baierd baierd self-assigned this Jun 22, 2023
@RSoegtrop
Copy link
Contributor

RSoegtrop commented Jul 6, 2023

@baierd I looked into it and found: equals in Z3Formula uses Native.isEqAst which returns true, if the long representation of the AST's are equal. bmgr.and(bmgr.and(var1, var2), bmgr.and(var3, var4)) and bmgr.and(var1, var2, var3, var4) yield the same string representation but a different long representation, due to the way they are generated. So equals in Z3Formula does not follow the description given in Formula. I fixed it by also checking the string representation for equality, which solves the issue but seems a bit sketchy.

I added some tests, but as it was mentioned above, simplification is missing, so they fail for every solver, except Z3 and SMTInterpol.

@kfriedberger
Copy link
Member

Formula::toString can be exponentially (!) bad in runtime and memory consumption. This is no acceptable solution.

@kfriedberger
Copy link
Member

Just as reminder, please take a look at the JavaDoc for Formula::equals :
https://github.com/sosy-lab/java-smt/blob/master/src/org/sosy_lab/java_smt/api/Formula.java#L28

 /**
   * checks whether the other object is a formula of the same structure. Does not apply an expensive
   * SAT-check to check equisatisfiability.
   *
   * <p>Two formulas that are structured in the same way, are determined as "equal". Due to
   * transformations and simplifications, two equisatisfiable formulas with different structure
   * might not be determined as "equal".
   */
  @Override
  boolean equals(Object other);

Is it really true that JavaSMT does violate this rule for the given formulas?

If really urgently required, we can use a FormulaVisitor to traverse formulas for equality in structure.

@PhilippWendler
Copy link
Member Author

Is it really true that JavaSMT does violate this rule for the given formulas?

I would say yes. The formulas have "the same structure" as we can see when we print them. I would also expect that traversing them yields the same structure (but I have not checked this).

I would suggest to check why the usual memoization of formulas does not happen as expected inside Z3 here, and potentially file a bug for Z3, if it violates its promises.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

When branches are created from issues, their pull requests are automatically linked.

4 participants