Skip to content

Commit bc00629

Browse files
committed
Optimise size to have approximate bound
This optimises the size function that was only used when checking for a bound. The new bounded_size takes an explicit bound argument and reduces the search when this bound is (approximately) reached.
1 parent b7859de commit bc00629

File tree

4 files changed

+26
-19
lines changed

4 files changed

+26
-19
lines changed

src/goto-symex/complexity_limiter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ complexity_limitert::check_complexity(goto_symex_statet &state)
136136
if(!complexity_limits_active() || !state.reachable)
137137
return complexity_violationt::NONE;
138138

139-
std::size_t complexity = state.complexity();
139+
std::size_t complexity = state.guard.as_expr().bounded_size(max_complexity);
140140
if(complexity == 0)
141141
return complexity_violationt::NONE;
142142

src/goto-symex/goto_state.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,15 +71,6 @@ class goto_statet
7171
/// Threads
7272
unsigned atomic_section_id = 0;
7373

74-
/// Get the complexity for this state. Used to short-circuit states if they
75-
/// have become too computationally complex.
76-
inline std::size_t complexity()
77-
{
78-
// TODO: This isn't too efficent for BDDs, try using a different size
79-
// like DAG size.
80-
return guard.as_expr().size();
81-
}
82-
8374
/// Constructors
8475
goto_statet() = delete;
8576
goto_statet &operator=(const goto_statet &other) = delete;

src/util/expr.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,28 @@ Author: Daniel Kroening, [email protected]
2424

2525
#include <stack>
2626

27-
std::size_t exprt::size() const
27+
/// Returns the size of the exprt added to count without searching significantly
28+
/// beyond the supplied limit.
29+
std::size_t exprt::bounded_size(std::size_t count, std::size_t limit) const
2830
{
29-
// Initial size of 1 to count self.
30-
std::size_t size = 1;
31-
for(const auto &op : operands())
31+
const auto &ops = operands();
32+
count += ops.size();
33+
for(const auto &op : ops)
3234
{
33-
size += op.size();
35+
if(count >= limit)
36+
{
37+
return count;
38+
}
39+
count = op.bounded_size(count, limit);
3440
}
41+
return count;
42+
}
3543

36-
return size;
44+
/// Returns the size of the exprt without significantly searching beyond the
45+
/// supplied limit.
46+
std::size_t exprt::bounded_size(std::size_t limit) const
47+
{
48+
return bounded_size(1, limit);
3749
}
3850

3951
/// Return whether the expression is a constant.

src/util/expr.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ class exprt:public irept
8585
return static_cast<const typet &>(find(ID_type));
8686
}
8787

88-
/// Amount of nodes this expression tree contains. This is the size of the
89-
/// actual tree, ignoring memory/sub-tree sharing.
90-
std::size_t size() const;
88+
/// Amount of nodes in this expression tree approximately bounded by limit.
89+
/// This is the size of the actual tree, ignoring memory/sub-tree sharing.
90+
std::size_t bounded_size(std::size_t limit) const;
9191

9292
/// Return true if there is at least one operand.
9393
bool has_operands() const
@@ -124,6 +124,10 @@ class exprt:public irept
124124
const exprt &op3() const
125125
{ return operands()[3]; }
126126

127+
/// Amount of nodes this expression tree contains, with a bound on how far
128+
/// to search. Starts with an existing count.
129+
std::size_t bounded_size(std::size_t count, std::size_t limit) const;
130+
127131
public:
128132
void reserve_operands(operandst::size_type n)
129133
{ operands().reserve(n) ; }

0 commit comments

Comments
 (0)