Skip to content

Conversation

@sim642
Copy link
Member

@sim642 sim642 commented Nov 21, 2024

Simplifications

  1. Use unary minus instead of subtraction from 0: 0 - x >= 0-x >= 0.
  2. Move constant to other side instead of always comparing with 0: -10 + x >= 0x >= 10.
  3. Don't add variables with coefficient 0. Apparently they are also iterated over.

TODO

  • Avoid negation on both sides: -x >= -55 >= x.
  • Avoid initial unary minus if possible: -x + y >= 0y - x >= 0.
  • Convert dual octagon inequalities into one equality: x >= 0 && -x >= 0x == 0.
    • Use for exact filtering (works automatically).
  • Avoid two constants: x + 5 = 0x = -5 (only happens if one side is default 0)? Needs ad-hoc logic and extra care to ensure unary minus does not overflow.

@sim642 sim642 added feature usability sv-comp SV-COMP (analyses, results), witnesses labels Nov 21, 2024
@sim642 sim642 self-assigned this Nov 21, 2024
@sim642 sim642 marked this pull request as ready for review December 9, 2024 13:15
@sim642 sim642 added this to the SV-COMP 2026 milestone Dec 9, 2024
@michael-schwarz
Copy link
Member

Are transformation such as avoid negation on both sides actually sound in the presence of overflows?

@sim642
Copy link
Member Author

sim642 commented Jan 14, 2025

Are transformation such as avoid negation on both sides actually sound in the presence of overflows?

If anything, I think it should avoid overflows. The constraint from Apron is on mathematical integers, so x doesn't overflow, while -x could.
Similarly in -x >= -5 if x is minimum long long, then the invariant would have an overflow, whereas 5 >= x would not.


Above I described a bunch of small simplifications based on invariants I've seen and how they would look nicer. I started out trying to implement such simplifications, but eventually realized that the following algorithm pretty much does it all: put all terms with positive coefficients on one side and all of the ones with negative coefficients to the other (while removing the negation). So it's just a comparison between two sums.

We're still casting everything to long long to minimize the chance of overflow, but neither the old nor the new implementation guarantees that. For example, x - y + z >= 0 is now written as x + z >= y, where it could be that x + z overflows, but subtracting y in between would avoid that.
But either way we're not systematically handling it. That would require somehow trying/optimizing the variable order to keep all intermediate results in bounds. And not just the order of variables, but the placement of the parenthesis to choose evaluation order.

@michael-schwarz
Copy link
Member

I think @DrMichaelPetter ran into some such issues when trying to assert constraints from his 2-variable domain, where doing some of these innocuous transformations lead to unsoundnesses. Maybe he can elaborate himself in the Gobcon today.

@DrMichaelPetter
Copy link
Collaborator

I think @DrMichaelPetter ran into some such issues ...

-x >= 5 was literally the constraint that was surprising me by overflowing in my experiments as well, when I synthesized constraints to propagate via event. We had a lengthy discussion and decided that unary minus was not particularly clever to choose for a synthesized constraint due to the inherent overflow.

@sim642 sim642 removed their assignment Feb 7, 2025
@sim642
Copy link
Member Author

sim642 commented Jul 10, 2025

Could either of you review this? This simplification is good for both human-readability and avoiding some obvious overflows.

Copy link
Collaborator

@DrMichaelPetter DrMichaelPetter left a comment

Choose a reason for hiding this comment

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

Ok, it took me some time to understand this idea of partitioning into pterms and nterms, but now I get it. LGTM

@sim642
Copy link
Member Author

sim642 commented Jul 15, 2025

Thanks! I added some comments to explain the partitioning and also the negation booleans that were there already before.

@sim642 sim642 merged commit 0862bee into master Jul 15, 2025
21 checks passed
@sim642 sim642 deleted the apron-invariant-simplify branch July 15, 2025 09:22
sim642 added a commit that referenced this pull request Jul 15, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature sv-comp SV-COMP (analyses, results), witnesses usability

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants