Merge lp:~tapaal-ltl/verifypn/kbound-fix-ltl into lp:verifypn
- kbound-fix-ltl
- Merge into new-trunk
Proposed by
Nikolaj Jensen Ulrik
Status: | Merged |
---|---|
Approved by: | Jiri Srba |
Approved revision: | 249 |
Merged at revision: | 250 |
Proposed branch: | lp:~tapaal-ltl/verifypn/kbound-fix-ltl |
Merge into: | lp:verifypn |
Diff against target: |
319 lines (+81/-42) 8 files modified
include/LTL/Algorithm/NestedDepthFirstSearch.h (+12/-12) include/LTL/Algorithm/TarjanModelChecker.h (+2/-1) include/LTL/Structures/BitProductStateSet.h (+5/-2) include/PetriEngine/PQL/Expressions.h (+1/-0) src/LTL/Algorithm/NestedDepthFirstSearch.cpp (+23/-14) src/LTL/Algorithm/TarjanModelChecker.cpp (+3/-0) src/LTL/LTLMain.cpp (+24/-12) src/PetriEngine/PQL/Expressions.cpp (+11/-1) |
To merge this branch: | bzr merge lp:~tapaal-ltl/verifypn/kbound-fix-ltl |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jiri Srba | Approve | ||
Peter Gjøl Jensen | Approve | ||
Review via email: mp+406929@code.launchpad.net |
Commit message
Description of the change
introduces k-bounds checking in Tarjan and in NDFS, fixing a bug with bad token counts in NDFS.
To post a comment you must log in.
- 249. By Nikolaj Jensen Ulrik
-
Fix 'A true' crashing the verifier in LTL mode
Revision history for this message
Peter Gjøl Jensen (peter-gjoel) : | # |
Revision history for this message
Nikolaj Jensen Ulrik (waefwerf) : | # |
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 'include/LTL/Algorithm/NestedDepthFirstSearch.h' | |||
2 | --- include/LTL/Algorithm/NestedDepthFirstSearch.h 2021-04-29 11:05:46 +0000 | |||
3 | +++ include/LTL/Algorithm/NestedDepthFirstSearch.h 2021-08-12 12:36:05 +0000 | |||
4 | @@ -49,10 +49,10 @@ | |||
5 | 49 | class NestedDepthFirstSearch : public ModelChecker<ProductSuccessorGenerator, SucGen> { | 49 | class NestedDepthFirstSearch : public ModelChecker<ProductSuccessorGenerator, SucGen> { |
6 | 50 | public: | 50 | public: |
7 | 51 | NestedDepthFirstSearch(const PetriEngine::PetriNet *net, const PetriEngine::PQL::Condition_ptr &query, | 51 | NestedDepthFirstSearch(const PetriEngine::PetriNet *net, const PetriEngine::PQL::Condition_ptr &query, |
9 | 52 | const Structures::BuchiAutomaton &buchi, SucGen *gen) | 52 | const Structures::BuchiAutomaton &buchi, SucGen *gen, int kbound) |
10 | 53 | : ModelChecker<ProductSuccessorGenerator, SucGen>(net, query, buchi, gen), | 53 | : ModelChecker<ProductSuccessorGenerator, SucGen>(net, query, buchi, gen), |
11 | 54 | factory{net, this->successorGenerator->initial_buchi_state()}, | 54 | factory{net, this->successorGenerator->initial_buchi_state()}, |
13 | 55 | states(*net, 0, (int) net->numberOfPlaces() + 1) {} | 55 | states(net, kbound) {} |
14 | 56 | 56 | ||
15 | 57 | bool isSatisfied() override; | 57 | bool isSatisfied() override; |
16 | 58 | 58 | ||
17 | @@ -87,16 +87,16 @@ | |||
18 | 87 | }; | 87 | }; |
19 | 88 | 88 | ||
20 | 89 | extern template | 89 | extern template |
31 | 90 | class NestedDepthFirstSearch<LTL::ResumingSuccessorGenerator, PetriEngine::Structures::StateSet>; | 90 | class NestedDepthFirstSearch<LTL::ResumingSuccessorGenerator, LTL::Structures::BitProductStateSet<>>; |
32 | 91 | 91 | ||
33 | 92 | extern template | 92 | extern template |
34 | 93 | class NestedDepthFirstSearch<LTL::ResumingSuccessorGenerator, PetriEngine::Structures::TracableStateSet>; | 93 | class NestedDepthFirstSearch<LTL::ResumingSuccessorGenerator, LTL::Structures::TraceableBitProductStateSet<>>; |
35 | 94 | 94 | ||
36 | 95 | extern template | 95 | extern template |
37 | 96 | class NestedDepthFirstSearch<LTL::SpoolingSuccessorGenerator, PetriEngine::Structures::StateSet>; | 96 | class NestedDepthFirstSearch<LTL::SpoolingSuccessorGenerator, LTL::Structures::BitProductStateSet<>>; |
38 | 97 | 97 | ||
39 | 98 | extern template | 98 | extern template |
40 | 99 | class NestedDepthFirstSearch<LTL::SpoolingSuccessorGenerator, PetriEngine::Structures::TracableStateSet>; | 99 | class NestedDepthFirstSearch<LTL::SpoolingSuccessorGenerator, LTL::Structures::TraceableBitProductStateSet<>>; |
41 | 100 | } | 100 | } |
42 | 101 | 101 | ||
43 | 102 | #endif //VERIFYPN_NESTEDDEPTHFIRSTSEARCH_H | 102 | #endif //VERIFYPN_NESTEDDEPTHFIRSTSEARCH_H |
44 | 103 | 103 | ||
45 | === modified file 'include/LTL/Algorithm/TarjanModelChecker.h' | |||
46 | --- include/LTL/Algorithm/TarjanModelChecker.h 2021-08-03 14:19:42 +0000 | |||
47 | +++ include/LTL/Algorithm/TarjanModelChecker.h 2021-08-12 12:36:05 +0000 | |||
48 | @@ -49,10 +49,11 @@ | |||
49 | 49 | TarjanModelChecker(const PetriEngine::PetriNet *net, const PetriEngine::PQL::Condition_ptr &cond, | 49 | TarjanModelChecker(const PetriEngine::PetriNet *net, const PetriEngine::PQL::Condition_ptr &cond, |
50 | 50 | const Structures::BuchiAutomaton &buchi, | 50 | const Structures::BuchiAutomaton &buchi, |
51 | 51 | SuccessorGen *successorGen, | 51 | SuccessorGen *successorGen, |
52 | 52 | int kbound, | ||
53 | 52 | std::unique_ptr<Spooler> &&...spooler) | 53 | std::unique_ptr<Spooler> &&...spooler) |
54 | 53 | : ModelChecker<ProductSucGen, SuccessorGen, Spooler...>(net, cond, buchi, successorGen, std::move(spooler)...), | 54 | : ModelChecker<ProductSucGen, SuccessorGen, Spooler...>(net, cond, buchi, successorGen, std::move(spooler)...), |
55 | 54 | factory(net, this->successorGenerator->initial_buchi_state()), | 55 | factory(net, this->successorGenerator->initial_buchi_state()), |
57 | 55 | seen(net, 0) | 56 | seen(net, kbound) |
58 | 56 | { | 57 | { |
59 | 57 | if (buchi._buchi->num_states() > 65535) { | 58 | if (buchi._buchi->num_states() > 65535) { |
60 | 58 | std::cerr << "Fatal error: cannot handle Büchi automata larger than 2^16 states\n"; | 59 | std::cerr << "Fatal error: cannot handle Büchi automata larger than 2^16 states\n"; |
61 | 59 | 60 | ||
62 | === modified file 'include/LTL/Structures/BitProductStateSet.h' | |||
63 | --- include/LTL/Structures/BitProductStateSet.h 2021-08-03 14:19:42 +0000 | |||
64 | +++ include/LTL/Structures/BitProductStateSet.h 2021-08-12 12:36:05 +0000 | |||
65 | @@ -94,8 +94,11 @@ | |||
66 | 94 | result_t add(const LTL::Structures::ProductState &state) override | 94 | result_t add(const LTL::Structures::ProductState &state) override |
67 | 95 | { | 95 | { |
68 | 96 | ++_discovered; | 96 | ++_discovered; |
71 | 97 | const auto[_, markingId] = markings.add(state); | 97 | const auto res = markings.add(state); |
72 | 98 | const stateid_t product_id = getProductId(markingId, state.getBuchiState()); | 98 | if (res.second == std::numeric_limits<size_t>::max()) { |
73 | 99 | return res; | ||
74 | 100 | } | ||
75 | 101 | const stateid_t product_id = getProductId(res.second, state.getBuchiState()); | ||
76 | 99 | 102 | ||
77 | 100 | const auto[iter, is_new] = states.insert(product_id); | 103 | const auto[iter, is_new] = states.insert(product_id); |
78 | 101 | assert(iter != std::end(states)); | 104 | assert(iter != std::end(states)); |
79 | 102 | 105 | ||
80 | === modified file 'include/PetriEngine/PQL/Expressions.h' | |||
81 | --- include/PetriEngine/PQL/Expressions.h 2021-07-07 13:19:23 +0000 | |||
82 | +++ include/PetriEngine/PQL/Expressions.h 2021-08-12 12:36:05 +0000 | |||
83 | @@ -489,6 +489,7 @@ | |||
84 | 489 | uint32_t retval = _cond->distance(context); | 489 | uint32_t retval = _cond->distance(context); |
85 | 490 | return retval; | 490 | return retval; |
86 | 491 | } | 491 | } |
87 | 492 | |||
88 | 492 | void visit(Visitor&) const override; | 493 | void visit(Visitor&) const override; |
89 | 493 | void visit(MutatingVisitor&) override; | 494 | void visit(MutatingVisitor&) override; |
90 | 494 | 495 | ||
91 | 495 | 496 | ||
92 | === modified file 'src/LTL/Algorithm/NestedDepthFirstSearch.cpp' | |||
93 | --- src/LTL/Algorithm/NestedDepthFirstSearch.cpp 2021-08-04 13:24:38 +0000 | |||
94 | +++ src/LTL/Algorithm/NestedDepthFirstSearch.cpp 2021-08-12 12:36:05 +0000 | |||
95 | @@ -40,9 +40,11 @@ | |||
96 | 40 | std::vector<State> initial_states = this->successorGenerator->makeInitialState(); | 40 | std::vector<State> initial_states = this->successorGenerator->makeInitialState(); |
97 | 41 | for (auto &state : initial_states) { | 41 | for (auto &state : initial_states) { |
98 | 42 | auto res = states.add(state); | 42 | auto res = states.add(state); |
102 | 43 | assert(res.first); | 43 | if (res.first) { |
103 | 44 | todo.push(StackEntry{res.second, S::initial_suc_info()}); | 44 | assert(res.first); |
104 | 45 | this->_discovered++; | 45 | todo.push(StackEntry{res.second, S::initial_suc_info()}); |
105 | 46 | this->_discovered++; | ||
106 | 47 | } | ||
107 | 46 | } | 48 | } |
108 | 47 | } | 49 | } |
109 | 48 | 50 | ||
110 | @@ -77,6 +79,9 @@ | |||
111 | 77 | } | 79 | } |
112 | 78 | } else { | 80 | } else { |
113 | 79 | auto[_, stateid] = states.add(working); | 81 | auto[_, stateid] = states.add(working); |
114 | 82 | if (stateid == std::numeric_limits<size_t>::max()) { | ||
115 | 83 | continue; | ||
116 | 84 | } | ||
117 | 80 | auto[it, is_new] = mark1.insert(stateid); | 85 | auto[it, is_new] = mark1.insert(stateid); |
118 | 81 | top.sucinfo.last_state = stateid; | 86 | top.sucinfo.last_state = stateid; |
119 | 82 | if (is_new) { | 87 | if (is_new) { |
120 | @@ -131,6 +136,9 @@ | |||
121 | 131 | return; | 136 | return; |
122 | 132 | } | 137 | } |
123 | 133 | auto[_, stateid] = states.add(working); | 138 | auto[_, stateid] = states.add(working); |
124 | 139 | if (stateid == std::numeric_limits<size_t>::max()) { | ||
125 | 140 | continue; | ||
126 | 141 | } | ||
127 | 134 | auto[it, is_new] = mark2.insert(stateid); | 142 | auto[it, is_new] = mark2.insert(stateid); |
128 | 135 | top.sucinfo.last_state = stateid; | 143 | top.sucinfo.last_state = stateid; |
129 | 136 | if (is_new) { | 144 | if (is_new) { |
130 | @@ -151,7 +159,7 @@ | |||
131 | 151 | { | 159 | { |
132 | 152 | std::cout << "STATS:\n" | 160 | std::cout << "STATS:\n" |
133 | 153 | << "\tdiscovered states: " << states.discovered() << std::endl | 161 | << "\tdiscovered states: " << states.discovered() << std::endl |
135 | 154 | << "\tmax tokens: " << states.maxTokens() << std::endl | 162 | << "\tmax tokens: " << states.max_tokens() << std::endl |
136 | 155 | << "\texplored states: " << mark1.size() << std::endl | 163 | << "\texplored states: " << mark1.size() << std::endl |
137 | 156 | << "\texplored states (nested): " << mark2.size() << std::endl; | 164 | << "\texplored states (nested): " << mark2.size() << std::endl; |
138 | 157 | } | 165 | } |
139 | @@ -181,14 +189,15 @@ | |||
140 | 181 | } | 189 | } |
141 | 182 | 190 | ||
142 | 183 | template | 191 | template |
153 | 184 | class NestedDepthFirstSearch<LTL::ResumingSuccessorGenerator, PetriEngine::Structures::StateSet>; | 192 | class NestedDepthFirstSearch<LTL::ResumingSuccessorGenerator, LTL::Structures::BitProductStateSet<>>; |
154 | 185 | 193 | ||
155 | 186 | template | 194 | template |
156 | 187 | class NestedDepthFirstSearch<LTL::ResumingSuccessorGenerator, PetriEngine::Structures::TracableStateSet>; | 195 | class NestedDepthFirstSearch<LTL::ResumingSuccessorGenerator, LTL::Structures::TraceableBitProductStateSet<>>; |
157 | 188 | 196 | ||
158 | 189 | template | 197 | template |
159 | 190 | class NestedDepthFirstSearch<LTL::SpoolingSuccessorGenerator, PetriEngine::Structures::StateSet>; | 198 | class NestedDepthFirstSearch<LTL::SpoolingSuccessorGenerator, LTL::Structures::BitProductStateSet<>>; |
160 | 191 | 199 | ||
161 | 192 | template | 200 | template |
162 | 193 | class NestedDepthFirstSearch<LTL::SpoolingSuccessorGenerator, PetriEngine::Structures::TracableStateSet>; | 201 | class NestedDepthFirstSearch<LTL::SpoolingSuccessorGenerator, LTL::Structures::TraceableBitProductStateSet<>>; |
163 | 202 | |||
164 | 194 | } | 203 | } |
165 | 195 | 204 | ||
166 | === modified file 'src/LTL/Algorithm/TarjanModelChecker.cpp' | |||
167 | --- src/LTL/Algorithm/TarjanModelChecker.cpp 2021-08-03 14:19:42 +0000 | |||
168 | +++ src/LTL/Algorithm/TarjanModelChecker.cpp 2021-08-12 12:36:05 +0000 | |||
169 | @@ -41,6 +41,9 @@ | |||
170 | 41 | } | 41 | } |
171 | 42 | ++this->stats.explored; | 42 | ++this->stats.explored; |
172 | 43 | const auto[isnew, stateid] = seen.add(working); | 43 | const auto[isnew, stateid] = seen.add(working); |
173 | 44 | if (stateid == std::numeric_limits<idx_t>::max()) { | ||
174 | 45 | continue; | ||
175 | 46 | } | ||
176 | 44 | 47 | ||
177 | 45 | if constexpr (SaveTrace) { | 48 | if constexpr (SaveTrace) { |
178 | 46 | if (isnew) { | 49 | if (isnew) { |
179 | 47 | 50 | ||
180 | === modified file 'src/LTL/LTLMain.cpp' | |||
181 | --- src/LTL/LTLMain.cpp 2021-08-04 12:57:39 +0000 | |||
182 | +++ src/LTL/LTLMain.cpp 2021-08-12 12:36:05 +0000 | |||
183 | @@ -153,14 +153,16 @@ | |||
184 | 153 | if (options.trace != TraceLevel::None) { | 153 | if (options.trace != TraceLevel::None) { |
185 | 154 | result = _verify( | 154 | result = _verify( |
186 | 155 | net, negated_formula, | 155 | net, negated_formula, |
189 | 156 | std::make_unique<NestedDepthFirstSearch<SpoolingSuccessorGenerator, PetriEngine::Structures::TracableStateSet>>( | 156 | std::make_unique<NestedDepthFirstSearch<SpoolingSuccessorGenerator, LTL::Structures::TraceableBitProductStateSet<> >>( |
190 | 157 | net, negated_formula, automaton, &gen), | 157 | net, negated_formula, automaton, &gen, |
191 | 158 | options.kbound), | ||
192 | 158 | options); | 159 | options); |
193 | 159 | } else { | 160 | } else { |
194 | 160 | result = _verify( | 161 | result = _verify( |
195 | 161 | net, negated_formula, | 162 | net, negated_formula, |
198 | 162 | std::make_unique<NestedDepthFirstSearch<SpoolingSuccessorGenerator, PetriEngine::Structures::StateSet>>( | 163 | std::make_unique<NestedDepthFirstSearch<SpoolingSuccessorGenerator, LTL::Structures::BitProductStateSet<> >>( |
199 | 163 | net, negated_formula, automaton, &gen), | 164 | net, negated_formula, automaton, &gen, |
200 | 165 | options.kbound), | ||
201 | 164 | options); | 166 | options); |
202 | 165 | } | 167 | } |
203 | 166 | } else { | 168 | } else { |
204 | @@ -168,14 +170,16 @@ | |||
205 | 168 | if (options.trace != TraceLevel::None) { | 170 | if (options.trace != TraceLevel::None) { |
206 | 169 | result = _verify( | 171 | result = _verify( |
207 | 170 | net, negated_formula, | 172 | net, negated_formula, |
210 | 171 | std::make_unique<NestedDepthFirstSearch<ResumingSuccessorGenerator, PetriEngine::Structures::TracableStateSet>>( | 173 | std::make_unique<NestedDepthFirstSearch<ResumingSuccessorGenerator, LTL::Structures::TraceableBitProductStateSet<> >>( |
211 | 172 | net, negated_formula, automaton, &gen), | 174 | net, negated_formula, automaton, &gen, |
212 | 175 | options.kbound), | ||
213 | 173 | options); | 176 | options); |
214 | 174 | } else { | 177 | } else { |
215 | 175 | result = _verify( | 178 | result = _verify( |
216 | 176 | net, negated_formula, | 179 | net, negated_formula, |
219 | 177 | std::make_unique<NestedDepthFirstSearch<ResumingSuccessorGenerator, PetriEngine::Structures::StateSet>>( | 180 | std::make_unique<NestedDepthFirstSearch<ResumingSuccessorGenerator, LTL::Structures::BitProductStateSet<> >>( |
220 | 178 | net, negated_formula, automaton, &gen), | 181 | net, negated_formula, automaton, &gen, |
221 | 182 | options.kbound), | ||
222 | 179 | options); | 183 | options); |
223 | 180 | } | 184 | } |
224 | 181 | } | 185 | } |
225 | @@ -213,6 +217,7 @@ | |||
226 | 213 | negated_formula, | 217 | negated_formula, |
227 | 214 | automaton, | 218 | automaton, |
228 | 215 | &gen, | 219 | &gen, |
229 | 220 | options.kbound, | ||
230 | 216 | std::make_unique<VisibleLTLStubbornSet>(*net, negated_formula)), | 221 | std::make_unique<VisibleLTLStubbornSet>(*net, negated_formula)), |
231 | 217 | options); | 222 | options); |
232 | 218 | } | 223 | } |
233 | @@ -223,6 +228,7 @@ | |||
234 | 223 | negated_formula, | 228 | negated_formula, |
235 | 224 | automaton, | 229 | automaton, |
236 | 225 | &gen, | 230 | &gen, |
237 | 231 | options.kbound, | ||
238 | 226 | std::make_unique<EnabledSpooler>(net, gen)), | 232 | std::make_unique<EnabledSpooler>(net, gen)), |
239 | 227 | options); | 233 | options); |
240 | 228 | } | 234 | } |
241 | @@ -232,7 +238,8 @@ | |||
242 | 232 | net, | 238 | net, |
243 | 233 | negated_formula, | 239 | negated_formula, |
244 | 234 | automaton, | 240 | automaton, |
246 | 235 | &gen), | 241 | &gen, |
247 | 242 | options.kbound), | ||
248 | 236 | options); | 243 | options); |
249 | 237 | } | 244 | } |
250 | 238 | } else { | 245 | } else { |
251 | @@ -244,6 +251,7 @@ | |||
252 | 244 | negated_formula, | 251 | negated_formula, |
253 | 245 | automaton, | 252 | automaton, |
254 | 246 | &gen, | 253 | &gen, |
255 | 254 | options.kbound, | ||
256 | 247 | std::make_unique<VisibleLTLStubbornSet>(*net, negated_formula)), | 255 | std::make_unique<VisibleLTLStubbornSet>(*net, negated_formula)), |
257 | 248 | options); | 256 | options); |
258 | 249 | } else if (is_autreach_stub && !is_visible_stub) { | 257 | } else if (is_autreach_stub && !is_visible_stub) { |
259 | @@ -253,6 +261,7 @@ | |||
260 | 253 | negated_formula, | 261 | negated_formula, |
261 | 254 | automaton, | 262 | automaton, |
262 | 255 | &gen, | 263 | &gen, |
263 | 264 | options.kbound, | ||
264 | 256 | std::make_unique<EnabledSpooler>(net, gen)), | 265 | std::make_unique<EnabledSpooler>(net, gen)), |
265 | 257 | options); | 266 | options); |
266 | 258 | } | 267 | } |
267 | @@ -262,7 +271,8 @@ | |||
268 | 262 | net, | 271 | net, |
269 | 263 | negated_formula, | 272 | negated_formula, |
270 | 264 | automaton, | 273 | automaton, |
272 | 265 | &gen), | 274 | &gen, |
273 | 275 | options.kbound), | ||
274 | 266 | options); | 276 | options); |
275 | 267 | } | 277 | } |
276 | 268 | } | 278 | } |
277 | @@ -276,7 +286,8 @@ | |||
278 | 276 | net, | 286 | net, |
279 | 277 | negated_formula, | 287 | negated_formula, |
280 | 278 | automaton, | 288 | automaton, |
282 | 279 | &gen), | 289 | &gen, |
283 | 290 | options.kbound), | ||
284 | 280 | options); | 291 | options); |
285 | 281 | } else { | 292 | } else { |
286 | 282 | result = _verify(net, negated_formula, | 293 | result = _verify(net, negated_formula, |
287 | @@ -284,7 +295,8 @@ | |||
288 | 284 | net, | 295 | net, |
289 | 285 | negated_formula, | 296 | negated_formula, |
290 | 286 | automaton, | 297 | automaton, |
292 | 287 | &gen), | 298 | &gen, |
293 | 299 | options.kbound), | ||
294 | 288 | options); | 300 | options); |
295 | 289 | } | 301 | } |
296 | 290 | } | 302 | } |
297 | 291 | 303 | ||
298 | === modified file 'src/PetriEngine/PQL/Expressions.cpp' | |||
299 | --- src/PetriEngine/PQL/Expressions.cpp 2021-07-07 13:19:23 +0000 | |||
300 | +++ src/PetriEngine/PQL/Expressions.cpp 2021-08-12 12:36:05 +0000 | |||
301 | @@ -3554,7 +3554,17 @@ | |||
302 | 3554 | 3554 | ||
303 | 3555 | Condition_ptr ACondition::prepareForReachability(bool negated) const { | 3555 | Condition_ptr ACondition::prepareForReachability(bool negated) const { |
304 | 3556 | auto g = std::dynamic_pointer_cast<GCondition>(_cond); | 3556 | auto g = std::dynamic_pointer_cast<GCondition>(_cond); |
306 | 3557 | return g ? AGCondition((*g)[0]).prepareForReachability(negated) : nullptr; | 3557 | if (g) { |
307 | 3558 | return AGCondition((*g)[0]).prepareForReachability(negated); | ||
308 | 3559 | } | ||
309 | 3560 | else { | ||
310 | 3561 | // ugly hacking for `A true`. | ||
311 | 3562 | auto bcond = std::dynamic_pointer_cast<BooleanCondition>(_cond); | ||
312 | 3563 | if (bcond) { | ||
313 | 3564 | return bcond; | ||
314 | 3565 | } | ||
315 | 3566 | else return nullptr; | ||
316 | 3567 | } | ||
317 | 3558 | } | 3568 | } |
318 | 3559 | 3569 | ||
319 | 3560 | Condition_ptr ECondition::prepareForReachability(bool negated) const { | 3570 | Condition_ptr ECondition::prepareForReachability(bool negated) const { |
LGTM.