@@ -72,16 +72,24 @@ normArgs sym conc l r = case (l, r) of
72
72
where
73
73
doOp = op2 sym conc
74
74
75
+ -- Same as `normArgs`, but for commutative operators it orders the arguments canonically
76
+ -- This helps in cases when (PEq x1 x2) is comparing x1 and x2 that are equivalent modulo commutativity.
77
+ -- In such cases, normArgsOrd will make sure x1 and x2 look the same.
78
+ normArgsOrd :: (Expr EWord -> Expr EWord -> Expr EWord ) -> (W256 -> W256 -> W256 ) -> Expr EWord -> Expr EWord -> Expr EWord
79
+ normArgsOrd sym conc l r = if l < r then doOp l r else doOp r l
80
+ where
81
+ doOp = op2 sym conc
82
+
75
83
-- Integers
76
84
77
85
add :: Expr EWord -> Expr EWord -> Expr EWord
78
- add = normArgs Add (+)
86
+ add = normArgsOrd Add (+)
79
87
80
88
sub :: Expr EWord -> Expr EWord -> Expr EWord
81
89
sub = op2 Sub (-)
82
90
83
91
mul :: Expr EWord -> Expr EWord -> Expr EWord
84
- mul = normArgs Mul (*)
92
+ mul = normArgsOrd Mul (*)
85
93
86
94
div :: Expr EWord -> Expr EWord -> Expr EWord
87
95
div = op2 Div (\ x y -> if y == 0 then 0 else Prelude. div x y)
@@ -156,21 +164,21 @@ sgt = op2 SGT (\x y ->
156
164
in if sx > sy then 1 else 0 )
157
165
158
166
eq :: Expr EWord -> Expr EWord -> Expr EWord
159
- eq = normArgs Eq (\ x y -> if x == y then 1 else 0 )
167
+ eq = normArgsOrd Eq (\ x y -> if x == y then 1 else 0 )
160
168
161
169
iszero :: Expr EWord -> Expr EWord
162
170
iszero = op1 IsZero (\ x -> if x == 0 then 1 else 0 )
163
171
164
172
-- Bits
165
173
166
174
and :: Expr EWord -> Expr EWord -> Expr EWord
167
- and = normArgs And (.&.)
175
+ and = normArgsOrd And (.&.)
168
176
169
177
or :: Expr EWord -> Expr EWord -> Expr EWord
170
- or = normArgs Or (.|.)
178
+ or = normArgsOrd Or (.|.)
171
179
172
180
xor :: Expr EWord -> Expr EWord -> Expr EWord
173
- xor = normArgs Xor Data.Bits. xor
181
+ xor = normArgsOrd Xor Data.Bits. xor
174
182
175
183
not :: Expr EWord -> Expr EWord
176
184
not = op1 Not complement
0 commit comments