Merge lp:~verifypn-cpn/verifypn/query_rewrite_fix into lp:verifypn
- query_rewrite_fix
- Merge into new-trunk
Proposed by
Peter Gjøl Jensen
Status: | Merged |
---|---|
Approved by: | Jiri Srba |
Approved revision: | 216 |
Merged at revision: | 213 |
Proposed branch: | lp:~verifypn-cpn/verifypn/query_rewrite_fix |
Merge into: | lp:verifypn |
Diff against target: |
370 lines (+123/-110) 3 files modified
PetriEngine/PQL/Contexts.h (+4/-2) PetriEngine/PQL/Expressions.cpp (+91/-107) PetriEngine/PQL/Expressions.h (+28/-1) |
To merge this branch: | bzr merge lp:~verifypn-cpn/verifypn/query_rewrite_fix |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jiri Srba | Approve | ||
Review via email: mp+353797@code.launchpad.net |
Commit message
Fixes wrong answer in CTLFireability from MCC2018 using
-x 2 ./SmallOperatin
Is consistent on 2017 models and queries.
Description of the change
To post a comment you must log in.
Revision history for this message
Jiri Srba (srba) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'PetriEngine/PQL/Contexts.h' | |||
2 | --- PetriEngine/PQL/Contexts.h 2018-03-09 18:37:07 +0000 | |||
3 | +++ PetriEngine/PQL/Contexts.h 2018-08-27 14:34:51 +0000 | |||
4 | @@ -144,6 +144,8 @@ | |||
5 | 144 | _marking = marking; | 144 | _marking = marking; |
6 | 145 | _net = net; | 145 | _net = net; |
7 | 146 | } | 146 | } |
8 | 147 | |||
9 | 148 | EvaluationContext() {}; | ||
10 | 147 | 149 | ||
11 | 148 | const MarkVal* marking() const { | 150 | const MarkVal* marking() const { |
12 | 149 | return _marking; | 151 | return _marking; |
13 | @@ -157,8 +159,8 @@ | |||
14 | 157 | return _net; | 159 | return _net; |
15 | 158 | } | 160 | } |
16 | 159 | private: | 161 | private: |
19 | 160 | const MarkVal* _marking; | 162 | const MarkVal* _marking = nullptr; |
20 | 161 | const PetriNet* _net; | 163 | const PetriNet* _net = nullptr; |
21 | 162 | }; | 164 | }; |
22 | 163 | 165 | ||
23 | 164 | /** Context for distance computation */ | 166 | /** Context for distance computation */ |
24 | 165 | 167 | ||
25 | === modified file 'PetriEngine/PQL/Expressions.cpp' | |||
26 | --- PetriEngine/PQL/Expressions.cpp 2018-05-12 15:14:12 +0000 | |||
27 | +++ PetriEngine/PQL/Expressions.cpp 2018-08-27 14:34:51 +0000 | |||
28 | @@ -69,8 +69,8 @@ | |||
29 | 69 | } | 69 | } |
30 | 70 | else | 70 | else |
31 | 71 | { | 71 | { |
34 | 72 | if(! ((dynamic_cast<UnfoldedIdentifierExpr*>((*comp)[0].get()) && dynamic_cast<LiteralExpr*>((*comp)[1].get())) || | 72 | if(! ((dynamic_cast<UnfoldedIdentifierExpr*>((*comp)[0].get()) && (*comp)[1]->placeFree()) || |
35 | 73 | (dynamic_cast<UnfoldedIdentifierExpr*>((*comp)[1].get()) && dynamic_cast<LiteralExpr*>((*comp)[0].get())))) | 73 | (dynamic_cast<UnfoldedIdentifierExpr*>((*comp)[1].get()) && (*comp)[0]->placeFree()))) |
36 | 74 | { | 74 | { |
37 | 75 | _conds.emplace_back(ptr); | 75 | _conds.emplace_back(ptr); |
38 | 76 | return; | 76 | return; |
39 | @@ -807,8 +807,7 @@ | |||
40 | 807 | context.marking()[c._place] >= c._lower; | 807 | context.marking()[c._place] >= c._lower; |
41 | 808 | if(!res) break; | 808 | if(!res) break; |
42 | 809 | } | 809 | } |
45 | 810 | 810 | return (_negated xor res) ? RTRUE : RFALSE; | |
44 | 811 | return _negated xor res ? RTRUE : RFALSE; | ||
46 | 812 | } | 811 | } |
47 | 813 | 812 | ||
48 | 814 | Condition::Result CompareCondition::evaluate(const EvaluationContext& context) { | 813 | Condition::Result CompareCondition::evaluate(const EvaluationContext& context) { |
49 | @@ -2486,8 +2485,15 @@ | |||
50 | 2486 | auto id = std::make_shared<UnfoldedIdentifierExpr>(c._name, c._place); | 2485 | auto id = std::make_shared<UnfoldedIdentifierExpr>(c._name, c._place); |
51 | 2487 | auto ll = std::make_shared<LiteralExpr>(c._lower); | 2486 | auto ll = std::make_shared<LiteralExpr>(c._lower); |
52 | 2488 | auto lu = std::make_shared<LiteralExpr>(c._upper); | 2487 | auto lu = std::make_shared<LiteralExpr>(c._upper); |
55 | 2489 | if (c._lower == c._upper && !neg) return std::make_shared<EqualCondition>(id, lu); | 2488 | if(c._lower == c._upper) |
56 | 2490 | else if(c._lower == c._upper && neg) return std::make_shared<NotEqualCondition>(id, lu); | 2489 | { |
57 | 2490 | if(c._lower != 0) | ||
58 | 2491 | if(neg) return std::make_shared<NotEqualCondition>(id, lu); | ||
59 | 2492 | else return std::make_shared<EqualCondition>(id, lu); | ||
60 | 2493 | else | ||
61 | 2494 | if(neg) return std::make_shared<GreaterThanCondition>(id, lu); | ||
62 | 2495 | else return std::make_shared<LessThanOrEqualCondition>(id, lu); | ||
63 | 2496 | } | ||
64 | 2491 | else | 2497 | else |
65 | 2492 | { | 2498 | { |
66 | 2493 | if(c._lower != 0 && c._upper != std::numeric_limits<uint32_t>::max()) | 2499 | if(c._lower != 0 && c._upper != std::numeric_limits<uint32_t>::max()) |
67 | @@ -3480,20 +3486,33 @@ | |||
68 | 3480 | }, stats, context, nested, negated, initrw); | 3486 | }, stats, context, nested, negated, initrw); |
69 | 3481 | } | 3487 | } |
70 | 3482 | 3488 | ||
71 | 3489 | Condition_ptr pushEqual(CompareCondition* org, bool negated, bool noteq, const EvaluationContext& context) | ||
72 | 3490 | { | ||
73 | 3491 | if(org->isTrivial()) return BooleanCondition::getShared(org->evaluate(context) xor negated); | ||
74 | 3492 | if((*org)[0]->placeFree() && (*org)[0]->evaluate(context) == 0) | ||
75 | 3493 | { | ||
76 | 3494 | if(negated == noteq) return std::make_shared<LessThanOrEqualCondition>((*org)[1], std::make_shared<LiteralExpr>(0)); | ||
77 | 3495 | else return std::make_shared<GreaterThanOrEqualCondition>((*org)[1], std::make_shared<LiteralExpr>(1)); | ||
78 | 3496 | } | ||
79 | 3497 | if((*org)[1]->placeFree() && (*org)[1]->evaluate(context) == 0) | ||
80 | 3498 | { | ||
81 | 3499 | if(negated == noteq) return std::make_shared<LessThanOrEqualCondition>((*org)[1], std::make_shared<LiteralExpr>(0)); | ||
82 | 3500 | else return std::make_shared<GreaterThanOrEqualCondition>((*org)[1], std::make_shared<LiteralExpr>(1)); | ||
83 | 3501 | } | ||
84 | 3502 | if(negated == noteq) return std::make_shared<EqualCondition>((*org)[0], (*org)[1]); | ||
85 | 3503 | else return std::make_shared<NotEqualCondition>((*org)[0], (*org)[1]); | ||
86 | 3504 | } | ||
87 | 3505 | |||
88 | 3483 | Condition_ptr NotEqualCondition::pushNegation(negstat_t& stats, const EvaluationContext& context, bool nested, bool negated, bool initrw) { | 3506 | Condition_ptr NotEqualCondition::pushNegation(negstat_t& stats, const EvaluationContext& context, bool nested, bool negated, bool initrw) { |
89 | 3484 | return initialMarkingRW([&]() -> Condition_ptr { | 3507 | return initialMarkingRW([&]() -> Condition_ptr { |
93 | 3485 | if(isTrivial()) return BooleanCondition::getShared(evaluate(context) xor negated); | 3508 | return pushEqual(this, negated, true, context); |
91 | 3486 | if(negated) return std::make_shared<EqualCondition>(_expr1, _expr2); | ||
92 | 3487 | else return std::make_shared<NotEqualCondition>(_expr1, _expr2); | ||
94 | 3488 | }, stats, context, nested, negated, initrw); | 3509 | }, stats, context, nested, negated, initrw); |
95 | 3489 | } | 3510 | } |
96 | 3490 | 3511 | ||
97 | 3491 | 3512 | ||
98 | 3492 | Condition_ptr EqualCondition::pushNegation(negstat_t& stats, const EvaluationContext& context, bool nested, bool negated, bool initrw) { | 3513 | Condition_ptr EqualCondition::pushNegation(negstat_t& stats, const EvaluationContext& context, bool nested, bool negated, bool initrw) { |
99 | 3493 | return initialMarkingRW([&]() -> Condition_ptr { | 3514 | return initialMarkingRW([&]() -> Condition_ptr { |
103 | 3494 | if(isTrivial()) return BooleanCondition::getShared(evaluate(context) xor negated); | 3515 | return pushEqual(this, negated, false, context); |
101 | 3495 | if(negated) return std::make_shared<NotEqualCondition>(_expr1, _expr2); | ||
102 | 3496 | else return std::make_shared<EqualCondition>(_expr1, _expr2); | ||
104 | 3497 | }, stats, context, nested, negated, initrw); | 3516 | }, stats, context, nested, negated, initrw); |
105 | 3498 | } | 3517 | } |
106 | 3499 | 3518 | ||
107 | @@ -3909,135 +3928,83 @@ | |||
108 | 3909 | exit(ErrorCode); | 3928 | exit(ErrorCode); |
109 | 3910 | } | 3929 | } |
110 | 3911 | auto il = _constraints.begin(); | 3930 | auto il = _constraints.begin(); |
112 | 3912 | for(auto& c : other._constraints) | 3931 | for(auto c : other._constraints) |
113 | 3913 | { | 3932 | { |
114 | 3933 | if(neg) | ||
115 | 3934 | c.invert(); | ||
116 | 3935 | |||
117 | 3936 | if(c._upper == std::numeric_limits<uint32_t>::max() && c._lower == 0) | ||
118 | 3937 | { | ||
119 | 3938 | continue; | ||
120 | 3939 | } | ||
121 | 3940 | else if (c._upper != std::numeric_limits<uint32_t>::max() && c._lower != 0 && neg) | ||
122 | 3941 | { | ||
123 | 3942 | std::cerr << "MERGE OF CONJUNCT AND DISJUNCT NOT ALLOWED" << std::endl; | ||
124 | 3943 | assert(false); | ||
125 | 3944 | exit(ErrorCode); | ||
126 | 3945 | } | ||
127 | 3946 | |||
128 | 3914 | il = std::lower_bound(_constraints.begin(), _constraints.end(), c); | 3947 | il = std::lower_bound(_constraints.begin(), _constraints.end(), c); |
167 | 3915 | cons_t c2; | 3948 | if(il == _constraints.end() || il->_place != c._place) |
168 | 3916 | if(neg) | 3949 | { |
169 | 3917 | { | 3950 | il = _constraints.insert(il, c); |
170 | 3918 | if(c._upper == 0) | 3951 | } |
171 | 3919 | { | 3952 | else |
172 | 3920 | c2._lower = 1; | 3953 | { |
173 | 3921 | } | 3954 | il->_lower = std::max(il->_lower, c._lower); |
174 | 3922 | else if (c._upper == std::numeric_limits<uint32_t>::max()) | 3955 | il->_upper = std::min(il->_upper, c._upper); |
137 | 3923 | { | ||
138 | 3924 | c2._upper = c._lower + (other._negated ? -1 : 1); | ||
139 | 3925 | } | ||
140 | 3926 | else if(c._lower == 0) | ||
141 | 3927 | { | ||
142 | 3928 | c2._lower = c._upper + (other._negated ? 1 : -1); | ||
143 | 3929 | } | ||
144 | 3930 | else | ||
145 | 3931 | { | ||
146 | 3932 | std::cerr << "MERGE OF CONJUNCT AND DISJUNCT NOT ALLOWED" << std::endl; | ||
147 | 3933 | assert(false); | ||
148 | 3934 | exit(ErrorCode); | ||
149 | 3935 | } | ||
150 | 3936 | c2._place = c._place; | ||
151 | 3937 | assert(c2._lower <= c2._upper); | ||
152 | 3938 | } | ||
153 | 3939 | else | ||
154 | 3940 | { | ||
155 | 3941 | c2 = c; | ||
156 | 3942 | } | ||
157 | 3943 | |||
158 | 3944 | if(il == _constraints.end() || il->_place != c2._place) | ||
159 | 3945 | { | ||
160 | 3946 | c2._name = c._name; | ||
161 | 3947 | il = _constraints.insert(il, c2); | ||
162 | 3948 | } | ||
163 | 3949 | else | ||
164 | 3950 | { | ||
165 | 3951 | il->_lower = std::max(il->_lower, c2._lower); | ||
166 | 3952 | il->_upper = std::min(il->_upper, c2._upper); | ||
175 | 3953 | } | 3956 | } |
176 | 3954 | } | 3957 | } |
177 | 3955 | } | 3958 | } |
178 | 3956 | 3959 | ||
179 | 3957 | void CompareConjunction::merge(const std::vector<Condition_ptr>& conditions, bool negated) | 3960 | void CompareConjunction::merge(const std::vector<Condition_ptr>& conditions, bool negated) |
180 | 3958 | { | 3961 | { |
181 | 3959 | |||
182 | 3960 | for(auto& c : conditions) | 3962 | for(auto& c : conditions) |
183 | 3961 | { | 3963 | { |
184 | 3962 | auto cmp = dynamic_cast<CompareCondition*>(c.get()); | 3964 | auto cmp = dynamic_cast<CompareCondition*>(c.get()); |
185 | 3963 | assert(cmp); | 3965 | assert(cmp); |
186 | 3964 | auto id = dynamic_cast<UnfoldedIdentifierExpr*>((*cmp)[0].get()); | 3966 | auto id = dynamic_cast<UnfoldedIdentifierExpr*>((*cmp)[0].get()); |
188 | 3965 | LiteralExpr* lit = nullptr; | 3967 | uint32_t val; |
189 | 3966 | bool inverted = false; | 3968 | bool inverted = false; |
190 | 3969 | EvaluationContext context; | ||
191 | 3967 | if(!id) | 3970 | if(!id) |
192 | 3968 | { | 3971 | { |
193 | 3969 | id = dynamic_cast<UnfoldedIdentifierExpr*>((*cmp)[1].get()); | 3972 | id = dynamic_cast<UnfoldedIdentifierExpr*>((*cmp)[1].get()); |
195 | 3970 | lit = dynamic_cast<LiteralExpr*>((*cmp)[0].get()); | 3973 | val = (*cmp)[0]->evaluate(context); |
196 | 3971 | inverted = true; | 3974 | inverted = true; |
197 | 3972 | } | 3975 | } |
198 | 3973 | else | 3976 | else |
199 | 3974 | { | 3977 | { |
201 | 3975 | lit = dynamic_cast<LiteralExpr*>((*cmp)[1].get()); | 3978 | val = (*cmp)[1]->evaluate(context); |
202 | 3976 | } | 3979 | } |
203 | 3977 | assert(lit); | ||
204 | 3978 | assert(id); | 3980 | assert(id); |
205 | 3979 | uint32_t val = lit->value(); | ||
206 | 3980 | cons_t next; | 3981 | cons_t next; |
207 | 3981 | next._place = id->offset(); | 3982 | next._place = id->offset(); |
208 | 3982 | auto lb = std::lower_bound(std::begin(_constraints), std::end(_constraints), next); | ||
209 | 3983 | if(lb == std::end(_constraints)) | ||
210 | 3984 | { | ||
211 | 3985 | next._name = id->name(); | ||
212 | 3986 | lb = _constraints.insert(lb, next); | ||
213 | 3987 | } | ||
214 | 3988 | else | ||
215 | 3989 | { | ||
216 | 3990 | assert(id->name().compare(lb->_name) == 0); | ||
217 | 3991 | } | ||
218 | 3992 | 3983 | ||
219 | 3993 | if(dynamic_cast<LessThanOrEqualCondition*>(c.get())) | 3984 | if(dynamic_cast<LessThanOrEqualCondition*>(c.get())) |
228 | 3994 | { | 3985 | if(inverted) next._lower = val; |
229 | 3995 | if(!negated) | 3986 | else next._upper = val; |
230 | 3996 | if(inverted) lb->_lower = std::max(lb->_lower, val); | 3987 | else if(dynamic_cast<LessThanCondition*>(c.get())) |
231 | 3997 | else lb->_upper = std::min(lb->_upper, val); | 3988 | if(inverted) next._lower = val+1; |
232 | 3998 | else | 3989 | else next._upper = val-1; |
225 | 3999 | if(!inverted) lb->_lower = std::max(lb->_lower, val+1); | ||
226 | 4000 | else lb->_upper = std::min(lb->_upper, val-1); | ||
227 | 4001 | } | ||
233 | 4002 | else if(dynamic_cast<GreaterThanOrEqualCondition*>(c.get())) | 3990 | else if(dynamic_cast<GreaterThanOrEqualCondition*>(c.get())) |
252 | 4003 | { | 3991 | if(inverted) next._upper = val; |
253 | 4004 | if(!negated) | 3992 | else next._lower = val; |
236 | 4005 | if(!inverted) lb->_lower = std::max(lb->_lower, val); | ||
237 | 4006 | else lb->_upper = std::min(lb->_upper, val); | ||
238 | 4007 | else | ||
239 | 4008 | if(inverted) lb->_lower = std::max(lb->_lower, val+1); | ||
240 | 4009 | else lb->_upper = std::min(lb->_upper, val-1); | ||
241 | 4010 | } | ||
242 | 4011 | else if(dynamic_cast<LessThanCondition*>(c.get())) | ||
243 | 4012 | { | ||
244 | 4013 | if(!negated) | ||
245 | 4014 | if(inverted) lb->_lower = std::max(lb->_lower, val+1); | ||
246 | 4015 | else lb->_upper = std::min(lb->_upper, val-1); | ||
247 | 4016 | else | ||
248 | 4017 | if(!inverted) lb->_lower = std::max(lb->_lower, val); | ||
249 | 4018 | else lb->_upper = std::min(lb->_upper, val); | ||
250 | 4019 | |||
251 | 4020 | } | ||
254 | 4021 | else if(dynamic_cast<GreaterThanCondition*>(c.get())) | 3993 | else if(dynamic_cast<GreaterThanCondition*>(c.get())) |
263 | 4022 | { | 3994 | if(inverted) next._upper = val-1; |
264 | 4023 | if(!negated) | 3995 | else next._lower = val+1; |
257 | 4024 | if(!inverted) lb->_lower = std::max(lb->_lower, val+1); | ||
258 | 4025 | else lb->_upper = std::min(lb->_upper, val-1); | ||
259 | 4026 | else | ||
260 | 4027 | if(inverted) lb->_lower = std::max(lb->_lower, val); | ||
261 | 4028 | else lb->_upper = std::min(lb->_upper, val); | ||
262 | 4029 | } | ||
265 | 4030 | else if(dynamic_cast<EqualCondition*>(c.get())) | 3996 | else if(dynamic_cast<EqualCondition*>(c.get())) |
266 | 4031 | { | 3997 | { |
267 | 4032 | assert(!negated); | 3998 | assert(!negated); |
270 | 4033 | lb->_lower = std::max(lb->_lower, val); | 3999 | next._lower = val; |
271 | 4034 | lb->_upper = std::min(lb->_upper, val); | 4000 | next._upper = val; |
272 | 4035 | } | 4001 | } |
273 | 4036 | else if(dynamic_cast<NotEqualCondition*>(c.get())) | 4002 | else if(dynamic_cast<NotEqualCondition*>(c.get())) |
274 | 4037 | { | 4003 | { |
275 | 4038 | assert(negated); | 4004 | assert(negated); |
278 | 4039 | lb->_lower = std::max(lb->_lower, val); | 4005 | next._lower = val; |
279 | 4040 | lb->_upper = std::min(lb->_upper, val); | 4006 | next._upper = val; |
280 | 4007 | negated = false; // we already handled negation here! | ||
281 | 4041 | } | 4008 | } |
282 | 4042 | else | 4009 | else |
283 | 4043 | { | 4010 | { |
284 | @@ -4045,14 +4012,31 @@ | |||
285 | 4045 | assert(false); | 4012 | assert(false); |
286 | 4046 | exit(ErrorCode); | 4013 | exit(ErrorCode); |
287 | 4047 | } | 4014 | } |
288 | 4015 | if(negated) | ||
289 | 4016 | next.invert(); | ||
290 | 4017 | |||
291 | 4018 | auto lb = std::lower_bound(std::begin(_constraints), std::end(_constraints), next); | ||
292 | 4019 | if(lb == std::end(_constraints) || lb->_place != next._place) | ||
293 | 4020 | { | ||
294 | 4021 | next._name = id->name(); | ||
295 | 4022 | _constraints.insert(lb, next); | ||
296 | 4023 | } | ||
297 | 4024 | else | ||
298 | 4025 | { | ||
299 | 4026 | assert(id->name().compare(lb->_name) == 0); | ||
300 | 4027 | lb->intersect(next); | ||
301 | 4028 | } | ||
302 | 4048 | } | 4029 | } |
303 | 4049 | } | 4030 | } |
304 | 4050 | 4031 | ||
305 | 4051 | void CommutativeExpr::init(std::vector<Expr_ptr>&& exprs) | 4032 | void CommutativeExpr::init(std::vector<Expr_ptr>&& exprs) |
306 | 4052 | { | 4033 | { |
307 | 4053 | for (auto& e : exprs) { | 4034 | for (auto& e : exprs) { |
310 | 4054 | if (auto lit = dynamic_pointer_cast<PQL::LiteralExpr>(e)) | 4035 | if (e->placeFree()) |
311 | 4055 | _constant = apply(_constant, lit->value()); | 4036 | { |
312 | 4037 | EvaluationContext c; | ||
313 | 4038 | _constant = apply(_constant, e->evaluate(c)); | ||
314 | 4039 | } | ||
315 | 4056 | else if (auto id = dynamic_pointer_cast<PQL::UnfoldedIdentifierExpr>(e)) { | 4040 | else if (auto id = dynamic_pointer_cast<PQL::UnfoldedIdentifierExpr>(e)) { |
316 | 4057 | _ids.emplace_back(id->offset(), id->name()); | 4041 | _ids.emplace_back(id->offset(), id->name()); |
317 | 4058 | } | 4042 | } |
318 | 4059 | 4043 | ||
319 | === modified file 'PetriEngine/PQL/Expressions.h' | |||
320 | --- PetriEngine/PQL/Expressions.h 2018-04-29 07:58:51 +0000 | |||
321 | +++ PetriEngine/PQL/Expressions.h 2018-08-27 14:34:51 +0000 | |||
322 | @@ -791,6 +791,33 @@ | |||
323 | 791 | { | 791 | { |
324 | 792 | return _place < other._place; | 792 | return _place < other._place; |
325 | 793 | } | 793 | } |
326 | 794 | |||
327 | 795 | void invert() | ||
328 | 796 | { | ||
329 | 797 | if(_lower == 0 && _upper == std::numeric_limits<uint32_t>::max()) | ||
330 | 798 | return; | ||
331 | 799 | assert(_lower == 0 || _upper == std::numeric_limits<uint32_t>::max()); | ||
332 | 800 | if(_lower == 0) | ||
333 | 801 | { | ||
334 | 802 | _lower = _upper + 1; | ||
335 | 803 | _upper = std::numeric_limits<uint32_t>::max(); | ||
336 | 804 | } | ||
337 | 805 | else if(_upper == std::numeric_limits<uint32_t>::max()) | ||
338 | 806 | { | ||
339 | 807 | _upper = _lower - 1; | ||
340 | 808 | _lower = 0; | ||
341 | 809 | } | ||
342 | 810 | else | ||
343 | 811 | { | ||
344 | 812 | assert(false); | ||
345 | 813 | } | ||
346 | 814 | } | ||
347 | 815 | |||
348 | 816 | void intersect(const cons_t& other) | ||
349 | 817 | { | ||
350 | 818 | _lower = std::max(_lower, other._lower); | ||
351 | 819 | _upper = std::min(_upper, other._upper); | ||
352 | 820 | } | ||
353 | 794 | }; | 821 | }; |
354 | 795 | 822 | ||
355 | 796 | CompareConjunction(bool negated = false) | 823 | CompareConjunction(bool negated = false) |
356 | @@ -884,13 +911,13 @@ | |||
357 | 884 | } | 911 | } |
358 | 885 | bool containsNext() const override { return false; } | 912 | bool containsNext() const override { return false; } |
359 | 886 | bool nestedDeadlock() const override { return false; } | 913 | bool nestedDeadlock() const override { return false; } |
360 | 914 | bool isTrivial() const; | ||
361 | 887 | protected: | 915 | protected: |
362 | 888 | uint32_t _distance(DistanceContext& c, | 916 | uint32_t _distance(DistanceContext& c, |
363 | 889 | std::function<uint32_t(uint32_t, uint32_t, bool)> d) const | 917 | std::function<uint32_t(uint32_t, uint32_t, bool)> d) const |
364 | 890 | { | 918 | { |
365 | 891 | return d(_expr1->evaluate(c), _expr2->evaluate(c), c.negated()); | 919 | return d(_expr1->evaluate(c), _expr2->evaluate(c), c.negated()); |
366 | 892 | } | 920 | } |
367 | 893 | bool isTrivial() const; | ||
368 | 894 | private: | 921 | private: |
369 | 895 | virtual bool apply(int v1, int v2) const = 0; | 922 | virtual bool apply(int v1, int v2) const = 0; |
370 | 896 | virtual std::string op() const = 0; | 923 | virtual std::string op() const = 0; |