55#ifndef CBMC_CHC_DB_H
66#define CBMC_CHC_DB_H
77
8+ #include < util/find_symbols.h>
89#include < util/mathematical_expr.h>
910#include < util/std_expr.h>
10- #include < util/find_symbols.h>
1111
12- #include < vector>
12+ #include " expr_iterator.h"
13+
14+ #include < functional>
1315#include < map>
1416#include < set>
15- #include < functional >
17+ #include < vector >
1618
1719class chc_dbt ;
1820
@@ -30,57 +32,54 @@ class horn_clauset
3032 forall_exprt m_chc;
3133
3234public:
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+ }
3638
39+ horn_clauset (std::vector<symbol_exprt> &vars, exprt clause)
40+ : m_chc(vars, clause)
41+ {
3742 }
3843
39- const forall_exprt & get_chc () const
44+ const forall_exprt &get_chc () const
4045 {
4146 return m_chc;
4247 }
4348
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 ()))
4652 {
4753 return &to_implies_expr (m_chc.where ()).op0 ();
4854 }
4955 return &m_chc.where ();
5056 }
5157
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 ()))
5461 {
5562 return &to_implies_expr (m_chc.where ()).op1 ();
5663 }
5764 return nullptr ;
5865 }
5966
60- bool is_fact () const {
67+ bool is_fact () const
68+ {
6169 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 ()))
7581 {
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 ()));
8483 }
8584 return false ;
8685 }
@@ -92,7 +91,7 @@ class horn_clauset
9291
9392 bool operator !=(const horn_clauset &other) const
9493 {
95- return !(*this == other);
94+ return !(*this == other);
9695 }
9796
9897 bool operator <(const horn_clauset &other) const
@@ -112,12 +111,19 @@ class horn_clauset
112111class chc_dbt
113112{
114113 friend class horn_clauset ;
114+
115115public:
116- struct is_state_pred : public std ::__unary_function<exprt, bool > {
116+ struct is_state_pred : public std ::__unary_function<exprt, bool >
117+ {
117118 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+ }
119122
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+ }
121127 };
122128
123129 typedef std::unordered_set<std::size_t > chc_sett;
@@ -136,37 +142,50 @@ class chc_dbt
136142 static chc_sett m_empty_set;
137143
138144public:
139- chc_dbt () {}
145+ chc_dbt ()
146+ {
147+ }
140148
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+ }
144161
145162 void build_indices ();
146163 void reset_indices ();
147164
148- const chc_sett & use (const exprt & state) const {
165+ const chc_sett &use (const exprt &state) const
166+ {
149167 auto it = m_body_idx.find (state);
150- if (it == m_body_idx.end ())
168+ if (it == m_body_idx.end ())
151169 return m_empty_set;
152170 return it->second ;
153171 }
154172
155- const chc_sett & def (const exprt & state) const {
173+ const chc_sett &def (const exprt &state) const
174+ {
156175 auto it = m_head_idx.find (state);
157- if (it == m_head_idx.end ())
176+ if (it == m_head_idx.end ())
158177 return m_empty_set;
159178 return it->second ;
160179 }
161180
162- void add_clause (const forall_exprt & f)
181+ void add_clause (const forall_exprt &f)
163182 {
164- if (f.is_true ())
183+ if (f.is_true ())
165184 return ;
166185 auto new_cls = horn_clauset (f);
167186 // Equivalent (semantic) queries may represent
168187 // different properties
169- if (!new_cls.is_query ())
188+ if (!new_cls.is_query ())
170189 {
171190 for (auto &c : m_clauses)
172191 {
@@ -178,16 +197,28 @@ class chc_dbt
178197 reset_indices ();
179198 }
180199
181- [[nodiscard]] const horn_clauset & get_clause (std::size_t idx) const
200+ [[nodiscard]] const horn_clauset &get_clause (std::size_t idx) const
182201 {
183202 INVARIANT (idx < m_clauses.size (), " Index in range" );
184203 return m_clauses[idx];
185204 }
186205
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+ }
191222};
192223
193224/*
@@ -197,7 +228,7 @@ class chc_dbt
197228 */
198229class chc_grapht
199230{
200- chc_dbt & m_db;
231+ chc_dbt &m_db;
201232 typedef std::map<exprt, std::unordered_set<exprt, irep_hash>> grapht;
202233 grapht m_incoming;
203234 grapht m_outgoing;
@@ -207,25 +238,36 @@ class chc_grapht
207238 static std::unordered_set<exprt, irep_hash> m_expr_empty_set;
208239
209240public:
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+ }
211244
212245 void build_graph ();
213246
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+ {
216253 INVARIANT (has_entry (), " Entry must exist." );
217- return m_entry; }
254+ return m_entry;
255+ }
218256
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+ {
220260 auto it = m_outgoing.find (state);
221- if (it == m_outgoing.end ())
261+ if (it == m_outgoing.end ())
222262 return m_expr_empty_set;
223263 return it->second ;
224264 }
225265
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+ {
227269 auto it = m_incoming.find (state);
228- if (it == m_incoming.end ())
270+ if (it == m_incoming.end ())
229271 return m_expr_empty_set;
230272 return it->second ;
231273 }
0 commit comments