@@ -32,6 +32,58 @@ class IntComparableExpr extends Expr {
32
32
}
33
33
}
34
34
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
+
35
87
/**
36
88
* An expression that directly tests whether a given expression is equal to `k` or not.
37
89
* 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) {
53
105
)
54
106
)
55
107
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
71
110
k = e .relevantInt ( ) and
72
- comp = result and
73
- comp .hasOperands ( e , c ) and
74
- bounded ( c , any ( ZeroBound zb ) , val , upper , _) and
75
111
is_k = false
76
112
|
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
95
114
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
125
116
)
126
117
}
127
118
0 commit comments