5
5
#ifndef CBMC_CHC_DB_H
6
6
#define CBMC_CHC_DB_H
7
7
8
+ #include < util/find_symbols.h>
8
9
#include < util/mathematical_expr.h>
9
10
#include < util/std_expr.h>
10
- #include < util/find_symbols.h>
11
11
12
- #include < vector>
12
+ #include " expr_iterator.h"
13
+
14
+ #include < functional>
13
15
#include < map>
14
16
#include < set>
15
- #include < functional >
17
+ #include < vector >
16
18
17
19
class chc_dbt ;
18
20
@@ -30,57 +32,54 @@ class horn_clauset
30
32
forall_exprt m_chc;
31
33
32
34
public:
33
- horn_clauset (forall_exprt f) : m_chc(f) {}
34
-
35
- horn_clauset (std::vector<symbol_exprt> & vars, exprt clause) : m_chc(vars, clause) {
35
+ horn_clauset (forall_exprt f) : m_chc(f)
36
+ {
37
+ }
36
38
39
+ horn_clauset (std::vector<symbol_exprt> &vars, exprt clause)
40
+ : m_chc(vars, clause)
41
+ {
37
42
}
38
43
39
- const forall_exprt & get_chc () const
44
+ const forall_exprt &get_chc () const
40
45
{
41
46
return m_chc;
42
47
}
43
48
44
- const exprt* body () const {
45
- if (can_cast_expr<implies_exprt>(m_chc.where ()))
49
+ const exprt *body () const
50
+ {
51
+ if (can_cast_expr<implies_exprt>(m_chc.where ()))
46
52
{
47
53
return &to_implies_expr (m_chc.where ()).op0 ();
48
54
}
49
55
return &m_chc.where ();
50
56
}
51
57
52
- const exprt* head () const {
53
- if (can_cast_expr<implies_exprt>(m_chc.where ()))
58
+ const exprt *head () const
59
+ {
60
+ if (can_cast_expr<implies_exprt>(m_chc.where ()))
54
61
{
55
62
return &to_implies_expr (m_chc.where ()).op1 ();
56
63
}
57
64
return nullptr ;
58
65
}
59
66
60
- bool is_fact () const {
67
+ bool is_fact () const
68
+ {
61
69
auto b = body ();
62
- bool not_fact = false ;
63
- b->visit_pre (
64
- [¬_fact](const exprt &expr) {
65
- if (can_cast_expr<function_application_exprt>(expr))
66
- {
67
- not_fact = true ;
68
- }
69
- });
70
- return !not_fact;
71
- }
72
-
73
- bool is_query () const {
74
- if (can_cast_expr<implies_exprt>(m_chc.where ()))
70
+ const std::function<bool (const exprt &)> pred = [](const exprt &subexpr) {
71
+ return can_cast_expr<function_application_exprt>(subexpr);
72
+ };
73
+ auto it = std::find_if (b->depth_begin (), b->depth_end (), pred);
74
+
75
+ return (it == b->depth_end ());
76
+ }
77
+
78
+ bool is_query () const
79
+ {
80
+ if (can_cast_expr<implies_exprt>(m_chc.where ()))
75
81
{
76
- auto h = head ();
77
- bool res = true ;
78
- h->visit_pre (
79
- [&res](const exprt &expr) {
80
- if (can_cast_expr<function_application_exprt>(expr))
81
- res = false ;
82
- });
83
- return res;
82
+ return (can_cast_expr<function_application_exprt>(*head ()));
84
83
}
85
84
return false ;
86
85
}
@@ -92,7 +91,7 @@ class horn_clauset
92
91
93
92
bool operator !=(const horn_clauset &other) const
94
93
{
95
- return !(*this == other);
94
+ return !(*this == other);
96
95
}
97
96
98
97
bool operator <(const horn_clauset &other) const
@@ -112,12 +111,19 @@ class horn_clauset
112
111
class chc_dbt
113
112
{
114
113
friend class horn_clauset ;
114
+
115
115
public:
116
- struct is_state_pred : public std ::__unary_function<exprt, bool > {
116
+ struct is_state_pred : public std ::__unary_function<exprt, bool >
117
+ {
117
118
const chc_dbt &m_db;
118
- is_state_pred (const chc_dbt &db) : m_db(db) {}
119
+ is_state_pred (const chc_dbt &db) : m_db(db)
120
+ {
121
+ }
119
122
120
- bool operator ()(symbol_exprt state) { return m_db.has_state_pred (state); }
123
+ bool operator ()(symbol_exprt state)
124
+ {
125
+ return m_db.has_state_pred (state);
126
+ }
121
127
};
122
128
123
129
typedef std::unordered_set<std::size_t > chc_sett;
@@ -136,37 +142,50 @@ class chc_dbt
136
142
static chc_sett m_empty_set;
137
143
138
144
public:
139
- chc_dbt () {}
145
+ chc_dbt ()
146
+ {
147
+ }
140
148
141
- void add_state_pred (const symbol_exprt & state) { m_state_preds.insert (state); }
142
- const std::unordered_set<symbol_exprt, irep_hash> &get_state_preds () { return m_state_preds; }
143
- bool has_state_pred (const symbol_exprt & state) const { return m_state_preds.count (state) > 0 ; }
149
+ void add_state_pred (const symbol_exprt &state)
150
+ {
151
+ m_state_preds.insert (state);
152
+ }
153
+ const std::unordered_set<symbol_exprt, irep_hash> &get_state_preds ()
154
+ {
155
+ return m_state_preds;
156
+ }
157
+ bool has_state_pred (const symbol_exprt &state) const
158
+ {
159
+ return m_state_preds.count (state) > 0 ;
160
+ }
144
161
145
162
void build_indices ();
146
163
void reset_indices ();
147
164
148
- const chc_sett & use (const exprt & state) const {
165
+ const chc_sett &use (const exprt &state) const
166
+ {
149
167
auto it = m_body_idx.find (state);
150
- if (it == m_body_idx.end ())
168
+ if (it == m_body_idx.end ())
151
169
return m_empty_set;
152
170
return it->second ;
153
171
}
154
172
155
- const chc_sett & def (const exprt & state) const {
173
+ const chc_sett &def (const exprt &state) const
174
+ {
156
175
auto it = m_head_idx.find (state);
157
- if (it == m_head_idx.end ())
176
+ if (it == m_head_idx.end ())
158
177
return m_empty_set;
159
178
return it->second ;
160
179
}
161
180
162
- void add_clause (const forall_exprt & f)
181
+ void add_clause (const forall_exprt &f)
163
182
{
164
- if (f.is_true ())
183
+ if (f.is_true ())
165
184
return ;
166
185
auto new_cls = horn_clauset (f);
167
186
// Equivalent (semantic) queries may represent
168
187
// different properties
169
- if (!new_cls.is_query ())
188
+ if (!new_cls.is_query ())
170
189
{
171
190
for (auto &c : m_clauses)
172
191
{
@@ -178,16 +197,28 @@ class chc_dbt
178
197
reset_indices ();
179
198
}
180
199
181
- [[nodiscard]] const horn_clauset & get_clause (std::size_t idx) const
200
+ [[nodiscard]] const horn_clauset &get_clause (std::size_t idx) const
182
201
{
183
202
INVARIANT (idx < m_clauses.size (), " Index in range" );
184
203
return m_clauses[idx];
185
204
}
186
205
187
- chcst::iterator begin () { return m_clauses.begin (); }
188
- chcst::iterator end () { return m_clauses.end (); }
189
- chcst::const_iterator begin () const { return m_clauses.begin (); }
190
- chcst::const_iterator end () const { return m_clauses.end (); }
206
+ chcst::iterator begin ()
207
+ {
208
+ return m_clauses.begin ();
209
+ }
210
+ chcst::iterator end ()
211
+ {
212
+ return m_clauses.end ();
213
+ }
214
+ chcst::const_iterator begin () const
215
+ {
216
+ return m_clauses.begin ();
217
+ }
218
+ chcst::const_iterator end () const
219
+ {
220
+ return m_clauses.end ();
221
+ }
191
222
};
192
223
193
224
/*
@@ -197,7 +228,7 @@ class chc_dbt
197
228
*/
198
229
class chc_grapht
199
230
{
200
- chc_dbt & m_db;
231
+ chc_dbt &m_db;
201
232
typedef std::map<exprt, std::unordered_set<exprt, irep_hash>> grapht;
202
233
grapht m_incoming;
203
234
grapht m_outgoing;
@@ -207,25 +238,36 @@ class chc_grapht
207
238
static std::unordered_set<exprt, irep_hash> m_expr_empty_set;
208
239
209
240
public:
210
- chc_grapht (chc_dbt & db) : m_db(db), m_entry(nullptr ) {}
241
+ chc_grapht (chc_dbt &db) : m_db(db), m_entry(nullptr )
242
+ {
243
+ }
211
244
212
245
void build_graph ();
213
246
214
- bool has_entry () const { return m_entry != nullptr ; }
215
- const symbol_exprt *entry () const {
247
+ bool has_entry () const
248
+ {
249
+ return m_entry != nullptr ;
250
+ }
251
+ const symbol_exprt *entry () const
252
+ {
216
253
INVARIANT (has_entry (), " Entry must exist." );
217
- return m_entry; }
254
+ return m_entry;
255
+ }
218
256
219
- const std::unordered_set<exprt, irep_hash> &outgoing (const symbol_exprt &state) const {
257
+ const std::unordered_set<exprt, irep_hash> &
258
+ outgoing (const symbol_exprt &state) const
259
+ {
220
260
auto it = m_outgoing.find (state);
221
- if (it == m_outgoing.end ())
261
+ if (it == m_outgoing.end ())
222
262
return m_expr_empty_set;
223
263
return it->second ;
224
264
}
225
265
226
- const std::unordered_set<exprt, irep_hash> &incoming (const symbol_exprt &state) const {
266
+ const std::unordered_set<exprt, irep_hash> &
267
+ incoming (const symbol_exprt &state) const
268
+ {
227
269
auto it = m_incoming.find (state);
228
- if (it == m_incoming.end ())
270
+ if (it == m_incoming.end ())
229
271
return m_expr_empty_set;
230
272
return it->second ;
231
273
}
0 commit comments