mirror of
https://github.com/Z3Prover/z3
synced 2025-10-22 23:44:34 +00:00
merge with master
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
commit
3533bf486f
223 changed files with 7175 additions and 2167 deletions
|
@ -86,13 +86,13 @@ static char const * get_new_param_name(std::string const & p) {
|
|||
template <typename T>
|
||||
class smap : public map<char const*, T, str_hash_proc, str_eq_proc> {};
|
||||
|
||||
typedef std::function<param_descrs*(void)> lazy_descrs_t;
|
||||
typedef param_descrs* (*lazy_descrs_t)(void);
|
||||
|
||||
class lazy_param_descrs {
|
||||
param_descrs* m_descrs;
|
||||
ptr_vector<lazy_descrs_t> m_mk;
|
||||
svector<lazy_descrs_t> m_mk;
|
||||
|
||||
void apply(lazy_descrs_t& f) {
|
||||
void apply(lazy_descrs_t f) {
|
||||
param_descrs* d = f();
|
||||
if (m_descrs) {
|
||||
m_descrs->copy(*d);
|
||||
|
@ -104,18 +104,16 @@ class lazy_param_descrs {
|
|||
}
|
||||
|
||||
void reset_mk() {
|
||||
for (auto* f : m_mk) dealloc(f);
|
||||
m_mk.reset();
|
||||
}
|
||||
|
||||
public:
|
||||
lazy_param_descrs(lazy_descrs_t& f): m_descrs(nullptr) {
|
||||
lazy_param_descrs(lazy_descrs_t f): m_descrs(nullptr) {
|
||||
append(f);
|
||||
}
|
||||
|
||||
~lazy_param_descrs() {
|
||||
dealloc(m_descrs);
|
||||
reset_mk();
|
||||
dealloc(m_descrs);
|
||||
}
|
||||
|
||||
param_descrs* deref() {
|
||||
|
@ -124,8 +122,8 @@ public:
|
|||
return m_descrs;
|
||||
}
|
||||
|
||||
void append(lazy_descrs_t& f) {
|
||||
m_mk.push_back(alloc(lazy_descrs_t, f));
|
||||
void append(lazy_descrs_t f) {
|
||||
m_mk.push_back(f);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -204,7 +202,7 @@ public:
|
|||
m_param_descrs.copy(d);
|
||||
}
|
||||
|
||||
void register_module(char const * module_name, lazy_descrs_t& f) {
|
||||
void register_module(char const * module_name, lazy_descrs_t f) {
|
||||
// Don't need synchronization here, this method
|
||||
// is invoked from check_registered that is already protected.
|
||||
|
||||
|
@ -278,20 +276,20 @@ public:
|
|||
strm << "the parameter '" << param_name
|
||||
<< "', invoke 'z3 -p' to obtain the new parameter list, and 'z3 -pp:" << new_name
|
||||
<< "' for the full description of the parameter";
|
||||
throw exception(strm.str());
|
||||
throw exception(std::move(strm).str());
|
||||
}
|
||||
else if (is_old_param_name(param_name)) {
|
||||
std::stringstream strm;
|
||||
strm << "unknown parameter '" << param_name
|
||||
<< "', this is an old parameter name, invoke 'z3 -p' to obtain the new parameter list";
|
||||
throw default_exception(strm.str());
|
||||
throw default_exception(std::move(strm).str());
|
||||
}
|
||||
else {
|
||||
std::stringstream strm;
|
||||
strm << "unknown parameter '" << param_name << "'\n";
|
||||
strm << "Legal parameters are:\n";
|
||||
d.display(strm, 2, false, false);
|
||||
throw default_exception(strm.str());
|
||||
throw default_exception(std::move(strm).str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -300,7 +298,7 @@ public:
|
|||
strm << "at module '" << mod_name << "'\n";
|
||||
strm << "Legal parameters are:\n";
|
||||
d.display(strm, 2, false, false);
|
||||
throw default_exception(strm.str());
|
||||
throw default_exception(std::move(strm).str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,7 +312,7 @@ public:
|
|||
if (!('0' <= *value && *value <= '9')) {
|
||||
strm << "Expected values for parameter " << name
|
||||
<< " is an unsigned integer. It was given argument '" << _value << "'";
|
||||
throw default_exception(strm.str());
|
||||
throw default_exception(std::move(strm).str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -323,7 +321,7 @@ public:
|
|||
if (!('0' <= *value && *value <= '9') && *value != '.' && *value != '-' && *value != '/') {
|
||||
strm << "Expected values for parameter " << name
|
||||
<< " is a double. It was given argument '" << _value << "'";
|
||||
throw default_exception(strm.str());
|
||||
throw default_exception(std::move(strm).str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -332,7 +330,7 @@ public:
|
|||
if (strcmp(value, "true") != 0 && strcmp(value, "false") != 0) {
|
||||
strm << "Expected values for parameter " << name
|
||||
<< " are 'true' or 'false'. It was given argument '" << value << "'";
|
||||
throw default_exception(strm.str());
|
||||
throw default_exception(std::move(strm).str());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -370,7 +368,7 @@ public:
|
|||
if (mod_name[0]) {
|
||||
strm << " at module '" << mod_name << "'";
|
||||
}
|
||||
throw default_exception(strm.str());
|
||||
throw default_exception(std::move(strm).str());
|
||||
}
|
||||
}
|
||||
else if (k == CPK_SYMBOL) {
|
||||
|
@ -387,7 +385,7 @@ public:
|
|||
if (mod_name[0]) {
|
||||
strm << " at module '" << mod_name << "'";
|
||||
}
|
||||
throw exception(strm.str());
|
||||
throw exception(std::move(strm).str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,7 +406,7 @@ public:
|
|||
else {
|
||||
std::stringstream strm;
|
||||
strm << "invalid parameter, unknown module '" << m << "'";
|
||||
throw exception(strm.str());
|
||||
throw exception(std::move(strm).str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -458,7 +456,7 @@ public:
|
|||
}
|
||||
std::stringstream strm;
|
||||
strm << "unknown module '" << m << "'";
|
||||
throw exception(strm.str());
|
||||
throw exception(std::move(strm).str());
|
||||
}
|
||||
|
||||
// unfortunately, params_ref is not thread safe
|
||||
|
@ -525,7 +523,7 @@ public:
|
|||
if (!get_module_param_descr(module_name, d)) {
|
||||
std::stringstream strm;
|
||||
strm << "unknown module '" << module_name << "'";
|
||||
throw exception(strm.str());
|
||||
throw exception(std::move(strm).str());
|
||||
}
|
||||
out << "[module] " << module_name;
|
||||
char const * descr = nullptr;
|
||||
|
@ -550,7 +548,7 @@ public:
|
|||
if (!get_module_param_descr(m, d)) {
|
||||
std::stringstream strm;
|
||||
strm << "unknown module '" << m << "'";
|
||||
throw exception(strm.str());
|
||||
throw exception(std::move(strm).str());
|
||||
}
|
||||
}
|
||||
if (!d->contains(sp))
|
||||
|
@ -599,7 +597,7 @@ void gparams::register_global(param_descrs & d) {
|
|||
g_imp->register_global(d);
|
||||
}
|
||||
|
||||
void gparams::register_module(char const * module_name, lazy_descrs_t& f) {
|
||||
void gparams::register_module(char const * module_name, lazy_descrs_t f) {
|
||||
SASSERT(g_imp);
|
||||
g_imp->register_module(module_name, f);
|
||||
}
|
||||
|
|
|
@ -85,8 +85,8 @@ public:
|
|||
module.
|
||||
*/
|
||||
|
||||
typedef std::function<param_descrs*(void)> lazy_descrs_t;
|
||||
static void register_module(char const* module_name, lazy_descrs_t& get_descrs);
|
||||
typedef param_descrs* (*lazy_descrs_t)(void);
|
||||
static void register_module(char const* module_name, lazy_descrs_t get_descrs);
|
||||
|
||||
/**
|
||||
\brief Add a (small) description to the given module.
|
||||
|
|
|
@ -20,7 +20,8 @@ Notes:
|
|||
|
||||
#include "util/vector.h"
|
||||
#include "util/uint_set.h"
|
||||
|
||||
#include "util/heap.h"
|
||||
#include "util/map.h"
|
||||
|
||||
template<class T>
|
||||
class max_cliques : public T {
|
||||
|
@ -43,12 +44,9 @@ class max_cliques : public T {
|
|||
m_seen1.insert(p);
|
||||
if (m_seen2.contains(p)) {
|
||||
unsigned_vector const& tc = m_tc[p];
|
||||
for (unsigned j = 0; j < tc.size(); ++j) {
|
||||
unsigned np = tc[j];
|
||||
if (goal.contains(np)) {
|
||||
for (unsigned np : tc)
|
||||
if (goal.contains(np))
|
||||
reachable.insert(np);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned np = negate(p);
|
||||
|
@ -61,29 +59,53 @@ class max_cliques : public T {
|
|||
for (unsigned i = m_todo.size(); i > 0; ) {
|
||||
--i;
|
||||
p = m_todo[i];
|
||||
if (m_seen2.contains(p)) {
|
||||
if (m_seen2.contains(p))
|
||||
continue;
|
||||
}
|
||||
m_seen2.insert(p);
|
||||
unsigned np = negate(p);
|
||||
unsigned_vector& tc = m_tc[p];
|
||||
if (goal.contains(np)) {
|
||||
if (goal.contains(np))
|
||||
tc.push_back(np);
|
||||
}
|
||||
else {
|
||||
unsigned_vector const& succ = next(np);
|
||||
for (unsigned j = 0; j < succ.size(); ++j) {
|
||||
tc.append(m_tc[succ[j]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
for (unsigned s : next(np))
|
||||
tc.append(m_tc[s]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned_vector const& next(unsigned vertex) const { return m_next[vertex]; }
|
||||
|
||||
void init(unsigned_vector const& ps) {
|
||||
unsigned max = 0;
|
||||
for (unsigned p : ps) {
|
||||
unsigned np = negate(p);
|
||||
max = std::max(max, std::max(np, p) + 1);
|
||||
}
|
||||
m_next.reserve(max);
|
||||
m_tc.reserve(m_next.size());
|
||||
}
|
||||
|
||||
struct compare_degree {
|
||||
u_map<uint_set>& conns;
|
||||
compare_degree(u_map<uint_set>& conns): conns(conns) {}
|
||||
bool operator()(unsigned x, unsigned y) const {
|
||||
return conns[x].num_elems() < conns[y].num_elems();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void init(unsigned_vector const& ps, u_map<uint_set>& conns) {
|
||||
|
||||
uint_set vars;
|
||||
|
||||
for (unsigned p : ps)
|
||||
vars.insert(p);
|
||||
|
||||
for (unsigned v : ps) {
|
||||
uint_set reach;
|
||||
get_reachable(v, vars, reach);
|
||||
conns.insert(v, reach);
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void add_edge(unsigned src, unsigned dst) {
|
||||
|
@ -93,21 +115,12 @@ public:
|
|||
m_next[dst].push_back(src);
|
||||
}
|
||||
|
||||
void cliques(unsigned_vector const& ps, vector<unsigned_vector>& cliques) {
|
||||
unsigned max = 0;
|
||||
unsigned num_ps = ps.size();
|
||||
for (unsigned i = 0; i < num_ps; ++i) {
|
||||
unsigned p = ps[i];
|
||||
unsigned np = negate(p);
|
||||
max = std::max(max, std::max(np, p) + 1);
|
||||
}
|
||||
m_next.reserve(max);
|
||||
m_tc.reserve(m_next.size());
|
||||
void cliques1(unsigned_vector const& ps, vector<unsigned_vector>& cliques) {
|
||||
init(ps);
|
||||
unsigned_vector clique;
|
||||
uint_set vars;
|
||||
for (unsigned i = 0; i < num_ps; ++i) {
|
||||
vars.insert(ps[i]);
|
||||
}
|
||||
for (unsigned v : ps)
|
||||
vars.insert(v);
|
||||
|
||||
while (!vars.empty()) {
|
||||
clique.reset();
|
||||
|
@ -118,9 +131,8 @@ public:
|
|||
m_reachable[turn].remove(p);
|
||||
vars.remove(p);
|
||||
clique.push_back(p);
|
||||
if (m_reachable[turn].empty()) {
|
||||
if (m_reachable[turn].empty())
|
||||
break;
|
||||
}
|
||||
m_reachable[!turn].reset();
|
||||
get_reachable(p, m_reachable[turn], m_reachable[!turn]);
|
||||
turn = !turn;
|
||||
|
@ -129,9 +141,75 @@ public:
|
|||
if (clique.size() == 2 && clique[0] == negate(clique[1])) {
|
||||
// no op
|
||||
}
|
||||
else {
|
||||
else
|
||||
cliques.push_back(clique);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// better quality cliques
|
||||
void cliques2(unsigned_vector const& ps, vector<unsigned_vector>& cs) {
|
||||
u_map<uint_set> conns;
|
||||
init(ps);
|
||||
// compute connections using TC of implication graph
|
||||
init(ps, conns);
|
||||
cliques(ps, conns, cs);
|
||||
}
|
||||
|
||||
// cliques after connections are computed.
|
||||
void cliques(unsigned_vector const& ps, u_map<uint_set>& conns, vector<unsigned_vector>& cliques) {
|
||||
|
||||
unsigned maxp = 1;
|
||||
for (unsigned p : ps)
|
||||
maxp = std::max(p, maxp);
|
||||
|
||||
uint_set todo;
|
||||
compare_degree lt(conns);
|
||||
heap<compare_degree> heap(maxp + 1, lt);
|
||||
|
||||
for (unsigned p : ps) {
|
||||
todo.insert(p);
|
||||
heap.insert(p);
|
||||
}
|
||||
|
||||
while (!todo.empty()) {
|
||||
unsigned v = heap.min_value();
|
||||
uint_set am1;
|
||||
unsigned_vector next;
|
||||
for (unsigned n : conns[v])
|
||||
if (todo.contains(n))
|
||||
next.push_back(n);
|
||||
std::sort(next.begin(), next.end(), [&](unsigned a, unsigned b) { return conns[a].num_elems() < conns[b].num_elems(); });
|
||||
for (unsigned x : next) {
|
||||
bool all = true;
|
||||
for (unsigned y : am1) {
|
||||
if (!conns[x].contains(y)) {
|
||||
all = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all)
|
||||
am1.insert(x);
|
||||
}
|
||||
am1.insert(v);
|
||||
for (unsigned x : am1) {
|
||||
todo.remove(x);
|
||||
for (unsigned y : conns[x]) {
|
||||
conns[y].remove(x);
|
||||
heap.decreased(y);
|
||||
}
|
||||
}
|
||||
for (unsigned x : am1)
|
||||
heap.erase(x);
|
||||
|
||||
if (am1.num_elems() > 1) {
|
||||
unsigned_vector mux;
|
||||
for (unsigned x : am1)
|
||||
mux.push_back(x);
|
||||
if (mux.size() == 2 && mux[0] == negate(mux[1])) {
|
||||
continue;
|
||||
}
|
||||
cliques.push_back(mux);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,15 +24,14 @@ Notes:
|
|||
|
||||
params_ref params_ref::g_empty_params_ref;
|
||||
|
||||
std::string norm_param_name(char const * n) {
|
||||
if (n == nullptr)
|
||||
return "_";
|
||||
std::string norm_param_name(char const* n) {
|
||||
if (*n == ':')
|
||||
n++;
|
||||
std::string r = n;
|
||||
unsigned sz = static_cast<unsigned>(r.size());
|
||||
if (sz == 0)
|
||||
return "_";
|
||||
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
char curr = r[i];
|
||||
if ('A' <= curr && curr <= 'Z')
|
||||
|
@ -44,6 +43,8 @@ std::string norm_param_name(char const * n) {
|
|||
}
|
||||
|
||||
std::string norm_param_name(symbol const & n) {
|
||||
if (n.is_null())
|
||||
return "_";
|
||||
return norm_param_name(n.bare_str());
|
||||
}
|
||||
|
||||
|
@ -156,8 +157,8 @@ struct param_descrs::imp {
|
|||
return m_names[idx];
|
||||
}
|
||||
|
||||
struct lt {
|
||||
bool operator()(symbol const & s1, symbol const & s2) const { return strcmp(s1.bare_str(), s2.bare_str()) < 0; }
|
||||
struct symlt {
|
||||
bool operator()(symbol const & s1, symbol const & s2) const { return ::lt(s1, s2); }
|
||||
};
|
||||
|
||||
void display(std::ostream & out, unsigned indent, bool smt2_style, bool include_descr) const {
|
||||
|
@ -165,13 +166,13 @@ struct param_descrs::imp {
|
|||
for (auto const& kv : m_info) {
|
||||
names.push_back(kv.m_key);
|
||||
}
|
||||
std::sort(names.begin(), names.end(), lt());
|
||||
std::sort(names.begin(), names.end(), symlt());
|
||||
for (symbol const& name : names) {
|
||||
for (unsigned i = 0; i < indent; i++) out << " ";
|
||||
if (smt2_style)
|
||||
out << ':';
|
||||
char const * s = name.bare_str();
|
||||
unsigned n = static_cast<unsigned>(strlen(s));
|
||||
std::string s = name.str();
|
||||
unsigned n = static_cast<unsigned>(s.length());
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
if (smt2_style && s[i] == '_')
|
||||
out << '-';
|
||||
|
|
|
@ -179,6 +179,10 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
rational& operator-=(int r) {
|
||||
(*this) -= rational(r);
|
||||
return *this;
|
||||
}
|
||||
|
||||
rational & operator*=(rational const & r) {
|
||||
m().mul(m_val, r.m_val, m_val);
|
||||
|
|
|
@ -76,56 +76,45 @@ static void thread_func(scoped_timer_state *s) {
|
|||
}
|
||||
|
||||
|
||||
struct scoped_timer::imp {
|
||||
private:
|
||||
scoped_timer_state *s;
|
||||
scoped_timer::scoped_timer(unsigned ms, event_handler * eh) {
|
||||
if (ms == 0 || ms == UINT_MAX)
|
||||
return;
|
||||
|
||||
public:
|
||||
imp(unsigned ms, event_handler * eh) {
|
||||
workers.lock();
|
||||
bool new_worker = false;
|
||||
if (available_workers.empty()) {
|
||||
workers.unlock();
|
||||
s = new scoped_timer_state;
|
||||
new_worker = true;
|
||||
++num_workers;
|
||||
}
|
||||
else {
|
||||
s = available_workers.back();
|
||||
available_workers.pop_back();
|
||||
workers.unlock();
|
||||
}
|
||||
s->ms = ms;
|
||||
s->eh = eh;
|
||||
s->m_mutex.lock();
|
||||
s->work = WORKING;
|
||||
if (new_worker) {
|
||||
s->m_thread = std::thread(thread_func, s);
|
||||
}
|
||||
else {
|
||||
s->cv.notify_one();
|
||||
}
|
||||
workers.lock();
|
||||
bool new_worker = false;
|
||||
if (available_workers.empty()) {
|
||||
workers.unlock();
|
||||
s = new scoped_timer_state;
|
||||
new_worker = true;
|
||||
++num_workers;
|
||||
}
|
||||
|
||||
~imp() {
|
||||
s->m_mutex.unlock();
|
||||
while (s->work == WORKING)
|
||||
std::this_thread::yield();
|
||||
workers.lock();
|
||||
available_workers.push_back(s);
|
||||
else {
|
||||
s = available_workers.back();
|
||||
available_workers.pop_back();
|
||||
workers.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
scoped_timer::scoped_timer(unsigned ms, event_handler * eh) {
|
||||
if (ms != UINT_MAX && ms != 0)
|
||||
m_imp = alloc(imp, ms, eh);
|
||||
else
|
||||
m_imp = nullptr;
|
||||
s->ms = ms;
|
||||
s->eh = eh;
|
||||
s->m_mutex.lock();
|
||||
s->work = WORKING;
|
||||
if (new_worker) {
|
||||
s->m_thread = std::thread(thread_func, s);
|
||||
}
|
||||
else {
|
||||
s->cv.notify_one();
|
||||
}
|
||||
}
|
||||
|
||||
scoped_timer::~scoped_timer() {
|
||||
dealloc(m_imp);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
s->m_mutex.unlock();
|
||||
while (s->work == WORKING)
|
||||
std::this_thread::yield();
|
||||
workers.lock();
|
||||
available_workers.push_back(s);
|
||||
workers.unlock();
|
||||
}
|
||||
|
||||
void scoped_timer::initialize() {
|
||||
|
|
|
@ -20,9 +20,10 @@ Revision History:
|
|||
|
||||
#include "util/event_handler.h"
|
||||
|
||||
struct scoped_timer_state;
|
||||
|
||||
class scoped_timer {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
scoped_timer_state *s = nullptr;
|
||||
public:
|
||||
scoped_timer(unsigned ms, event_handler * eh);
|
||||
~scoped_timer();
|
||||
|
|
|
@ -216,7 +216,7 @@ int zstring::indexofu(zstring const& other, unsigned offset) const {
|
|||
int zstring::last_indexof(zstring const& other) const {
|
||||
if (other.length() == 0) return length();
|
||||
if (other.length() > length()) return -1;
|
||||
for (unsigned last = length() - other.length(); last-- > 0; ) {
|
||||
for (unsigned last = length() - other.length() + 1; last-- > 0; ) {
|
||||
bool suffix = true;
|
||||
for (unsigned j = 0; suffix && j < other.length(); ++j) {
|
||||
suffix = m_buffer[last + j] == other[j];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue