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

Do not simplify equality immediately on construction #546

Merged
merged 1 commit into from
Aug 28, 2024

Conversation

blishko
Copy link
Collaborator

@blishko blishko commented Aug 28, 2024

Description

As @zoep pointed out it might be preferable to keep simplification code in the simplification functions and do not simplify equalities directly at construction point.

However, we would still like to normalize equalities, so that constants are at LHS. Therefore we update the simplification rules, which were previously written to expect constant on RHS.

Checklist

  • tested locally
  • added automated tests
  • updated the docs
  • updated the changelog

@blishko blishko requested review from msooseth and zoep August 28, 2024 05:47
Copy link
Collaborator

@zoep zoep left a comment

Choose a reason for hiding this comment

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

Thanks Martin! This looks great. Just a small nit:

Since the logic for argument normalisation for Expr operators is in Expr.hs and already has a naming convention, it would make sense to have the same operators for Prop in the same file and with the same naming convention. Therefore, I would suggest moving mkPEq to Expr.hs and renaming it to peq for consistency.

src/EVM/Expr.hs Outdated
@@ -1214,29 +1214,29 @@ simplifyProp prop =
go (PLEq a (Max _ b)) | a == b = PBool True
go (PLEq (Sub a b) c) | a == c = PLEq b a
go (PLT (Max (Lit a) b) (Lit c)) | a < c = PLT b (Lit c)
go (PLT (Lit 0) (Eq a b)) = mkPEq a b
go (PLT (Lit 0) (Eq a b)) = PEq a b
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand this... it's under simplifyProp, why not do mkPEq here? It's the most obvious thing to do I think? I must be not getting something. Under simplify, which simplifies Expr, we have:

    go (IsZero (IsZero (Eq x y))) = eq x y

Which is exactly the same idea -- eq will set the LHS, etc. So we seem to be inconsistent.

I don't mind it too much, but I just don't understand. Can you maybe explain what's the rationale and why is that eq ok, but this mkPEq not ok?

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 agree that here it would be good to simplify immediately. Do you agree as well, @zoep?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I agree that for consistency it would be better to use peq/mkPEq here (though I understand that it doesn't matter so much as it will be simplified in the next iteration)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, we would get to it on next iteration, it's true :)

src/EVM/Expr.hs Outdated
Comment on lines 1259 to 1277
go (PEq (IsZero (Eq a b)) (Lit 0)) = mkPEq a b
go (PEq (IsZero (LT a b)) (Lit 0)) = PLT a b
go (PEq (IsZero (GT a b)) (Lit 0)) = PGT a b
go (PEq (IsZero (LEq a b)) (Lit 0)) = PLEq a b
go (PEq (IsZero (GEq a b)) (Lit 0)) = PGEq a b
go (PEq (Lit 0) (IsZero (Eq a b))) = PEq a b
go (PEq (Lit 0) (IsZero (LT a b))) = PLT a b
go (PEq (Lit 0) (IsZero (GT a b))) = PGT a b
go (PEq (Lit 0) (IsZero (LEq a b))) = PLEq a b
go (PEq (Lit 0) (IsZero (GEq a b))) = PGEq a b

-- Eq
go (PEq (Eq a b) (Lit 0)) = PNeg (mkPEq a b)
go (PEq (Eq a b) (Lit 1)) = mkPEq a b
go (PEq (Sub a b) (Lit 0)) = mkPEq a b
go (PEq (LT a b) (Lit 0)) = PLEq b a
go (PEq (Lit l) (Lit r)) = PBool (l == r)
Copy link
Collaborator

Choose a reason for hiding this comment

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

These are great, thank you so much!

src/EVM/Expr.hs Outdated
Comment on lines 1224 to 1246
go (PEq (IsZero (IsZero (Eq a b))) (Lit 0)) = PNeg (mkPEq a b)
go (PEq (Lit 0) (IsZero (IsZero (Eq a b)))) = PNeg (PEq a b)

-- iszero(a) -> (a == 0)
-- iszero(iszero(a))) -> ~(a == 0) -> a > 0
-- iszero(iszero(a)) == 0 -> ~~(a == 0) -> a == 0
-- ~(iszero(iszero(a)) == 0) -> ~~~(a == 0) -> ~(a == 0) -> a > 0
go (PNeg (PEq (IsZero (IsZero a)) (Lit 0))) = PLT (Lit 0) a
go (PNeg (PEq (Lit 0) (IsZero (IsZero a)))) = PLT (Lit 0) a

-- iszero(a) -> (a == 0)
-- iszero(a) == 0 -> ~(a == 0)
-- ~(iszero(a) == 0) -> ~~(a == 0) -> a == 0
go (PNeg (PEq (IsZero a) (Lit 0))) = mkPEq (Lit 0) a
go (PNeg (PEq (Lit 0) (IsZero a))) = PEq (Lit 0) a

-- a < b == 0 -> ~(a < b)
-- ~(a < b == 0) -> ~~(a < b) -> a < b
go (PNeg (PEq (LT a b) (Lit 0x0))) = PLT a b
Copy link
Collaborator

Choose a reason for hiding this comment

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

Soooo good thanks!! 👍

src/EVM.hs Show resolved Hide resolved
src/EVM/Expr.hs Outdated

-- iszero(a) -> (a == 0)
-- iszero(a) == 0 -> ~(a == 0)
-- ~(iszero(a) == 0) -> ~~(a == 0) -> a == 0
go (PNeg (PEq (IsZero a) (Lit 0))) = mkPEq (Lit 0) a
go (PNeg (PEq (Lit 0) (IsZero a))) = PEq (Lit 0) a
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd change this to mkPEq

src/EVM/Expr.hs Outdated

-- negations
go (PNeg (PBool b)) = PBool (Prelude.not b)
go (PNeg (PNeg a)) = a

-- solc specific stuff
go (PEq (IsZero (IsZero (Eq a b))) (Lit 0)) = PNeg (mkPEq a b)
go (PEq (Lit 0) (IsZero (IsZero (Eq a b)))) = PNeg (PEq a b)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd change this to mkPEq

Copy link
Collaborator

@msooseth msooseth left a comment

Choose a reason for hiding this comment

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

I'm fine either way, using mkPEq in simplifyProps would make sense I think, but it's fine either way! It's better not to simplify during creation, it's very true!

@blishko blishko marked this pull request as draft August 28, 2024 10:19
After some discussion, it turns out it is preferable to keep
simplification code in the simplification functions and do not simplify
equalities directly at construction point.

However, we would still like to normalize equalities, so that constants
are at LHS. Therefore we update the simplification rules, which were
previously written to expect constant on RHS.
@blishko blishko force-pushed the fix-equality-simplification branch from 5fb3246 to b6753d8 Compare August 28, 2024 10:24
@blishko blishko marked this pull request as ready for review August 28, 2024 10:27
Copy link
Collaborator

@zoep zoep left a comment

Choose a reason for hiding this comment

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

LGTM!

@msooseth
Copy link
Collaborator

Perfect, thanks, merging!

@msooseth msooseth merged commit 621f614 into main Aug 28, 2024
9 checks passed
@msooseth msooseth deleted the fix-equality-simplification branch August 28, 2024 10:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants