@@ -32,6 +32,58 @@ class IntComparableExpr extends Expr {
3232 }
3333}
3434
35+ /**
36+ * Holds if `comp` evaluating to `branch` ensures that `e1` is less than `e2`.
37+ * When `strict` is true, `e1` is strictly less than `e2`, otherwise it is less
38+ * than or equal to `e2`.
39+ */
40+ private predicate comparison ( ComparisonExpr comp , boolean branch , Expr e1 , Expr e2 , boolean strict ) {
41+ branch = true and
42+ e1 = comp .getLesserOperand ( ) and
43+ e2 = comp .getGreaterOperand ( ) and
44+ ( if comp .isStrict ( ) then strict = true else strict = false )
45+ or
46+ branch = false and
47+ e1 = comp .getGreaterOperand ( ) and
48+ e2 = comp .getLesserOperand ( ) and
49+ ( if comp .isStrict ( ) then strict = false else strict = true )
50+ }
51+
52+ /**
53+ * Holds if `guard` evaluating to `branch` ensures that:
54+ * `e <= k` when `upper = true`
55+ * `e >= k` when `upper = false`
56+ */
57+ pragma [ nomagic]
58+ predicate rangeGuard ( Expr guard , boolean branch , Expr e , int k , boolean upper ) {
59+ exists ( EqualityTest eqtest , Expr c |
60+ eqtest = guard and
61+ eqtest .hasOperands ( e , c ) and
62+ bounded ( c , any ( ZeroBound zb ) , k , upper , _) and
63+ branch = eqtest .polarity ( )
64+ )
65+ or
66+ exists ( Expr c , int val , boolean strict , int d |
67+ bounded ( c , any ( ZeroBound zb ) , val , upper , _) and
68+ (
69+ upper = true and
70+ comparison ( guard , branch , e , c , strict ) and
71+ d = - 1
72+ or
73+ upper = false and
74+ comparison ( guard , branch , c , e , strict ) and
75+ d = 1
76+ ) and
77+ (
78+ strict = false and k = val
79+ or
80+ // e < c <= val ==> e <= c - 1 <= val - 1
81+ // e > c >= val ==> e >= c + 1 >= val + 1
82+ strict = true and k = val + d
83+ )
84+ )
85+ }
86+
3587/**
3688 * An expression that directly tests whether a given expression is equal to `k` or not.
3789 * The set of `k`s is restricted to those that are relevant for the expression or
@@ -53,75 +105,14 @@ Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) {
53105 )
54106 )
55107 or
56- exists ( EqualityTest eqtest , int val , Expr c , boolean upper |
57- k = e .relevantInt ( ) and
58- eqtest = result and
59- eqtest .hasOperands ( e , c ) and
60- bounded ( c , any ( ZeroBound zb ) , val , upper , _) and
61- is_k = false and
62- (
63- upper = true and val < k
64- or
65- upper = false and val > k
66- ) and
67- branch = eqtest .polarity ( )
68- )
69- or
70- exists ( ComparisonExpr comp , Expr c , int val , boolean upper |
108+ exists ( int val , boolean upper |
109+ rangeGuard ( result , branch , e , val , upper ) and
71110 k = e .relevantInt ( ) and
72- comp = result and
73- comp .hasOperands ( e , c ) and
74- bounded ( c , any ( ZeroBound zb ) , val , upper , _) and
75111 is_k = false
76112 |
77- // k <= val <= c < e, so e != k
78- comp .getLesserOperand ( ) = c and
79- comp .isStrict ( ) and
80- branch = true and
81- val >= k and
82- upper = false
83- or
84- comp .getLesserOperand ( ) = c and
85- comp .isStrict ( ) and
86- branch = false and
87- val < k and
88- upper = true
89- or
90- comp .getLesserOperand ( ) = c and
91- not comp .isStrict ( ) and
92- branch = true and
93- val > k and
94- upper = false
113+ upper = true and val < k // e <= val < k ==> e != k
95114 or
96- comp .getLesserOperand ( ) = c and
97- not comp .isStrict ( ) and
98- branch = false and
99- val <= k and
100- upper = true
101- or
102- comp .getGreaterOperand ( ) = c and
103- comp .isStrict ( ) and
104- branch = true and
105- val <= k and
106- upper = true
107- or
108- comp .getGreaterOperand ( ) = c and
109- comp .isStrict ( ) and
110- branch = false and
111- val > k and
112- upper = false
113- or
114- comp .getGreaterOperand ( ) = c and
115- not comp .isStrict ( ) and
116- branch = true and
117- val < k and
118- upper = true
119- or
120- comp .getGreaterOperand ( ) = c and
121- not comp .isStrict ( ) and
122- branch = false and
123- val >= k and
124- upper = false
115+ upper = false and val > k // e >= val > k ==> e != k
125116 )
126117}
127118
0 commit comments