3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-12 14:10:54 +00:00

Merge branch 'master' into polysat

This commit is contained in:
Jakob Rath 2022-07-01 16:11:17 +02:00
commit e5e79c1d4b
398 changed files with 24548 additions and 4983 deletions

View file

@ -485,6 +485,26 @@ namespace opt {
}
}
model_based_opt::row& model_based_opt::row::normalize() {
#if 0
if (m_type == t_mod)
return *this;
rational D(denominator(abs(m_coeff)));
if (D == 0)
D = 1;
for (auto const& [id, coeff] : m_vars)
if (coeff != 0)
D = lcm(D, denominator(abs(coeff)));
if (D == 1)
return *this;
SASSERT(D > 0);
for (auto & [id, coeff] : m_vars)
coeff *= D;
m_coeff *= D;
#endif
return *this;
}
//
// Let
// row1: t1 + a1*x <= 0
@ -923,9 +943,9 @@ namespace opt {
}
void model_based_opt::get_live_rows(vector<row>& rows) {
for (row const& r : m_rows) {
for (row & r : m_rows) {
if (r.m_alive) {
rows.push_back(r);
rows.push_back(r.normalize());
}
}
}

View file

@ -59,6 +59,7 @@ namespace opt {
bool m_alive; // rows can be marked dead if they have been processed.
void reset() { m_vars.reset(); m_coeff.reset(); m_value.reset(); }
row& normalize();
void neg() { for (var & v : m_vars) v.m_coeff.neg(); m_coeff.neg(); m_value.neg(); }
rational get_coefficient(unsigned x) const;
};

View file

@ -18,6 +18,7 @@ Notes:
--*/
#include "math/simplex/simplex.h"
#include "math/simplex/sparse_matrix_ops.h"
#include "math/simplex/sparse_matrix_def.h"
#include "math/simplex/simplex_def.h"
#include "util/rational.h"
@ -36,6 +37,9 @@ namespace simplex {
}
}
void kernel(sparse_matrix<mpq_ext>& M, vector<vector<rational>>& K) {
sparse_matrix_ops::kernel(M, K);
}
void ensure_rational_solution(simplex<mpq_ext>& S) {
rational delta(1);

View file

@ -33,6 +33,7 @@ Notes:
#include "math/simplex/sparse_matrix.h"
#include "util/mpq_inf.h"
#include "util/rational.h"
#include "util/heap.h"
#include "util/lbool.h"
#include "util/uint_set.h"
@ -200,5 +201,7 @@ namespace simplex {
};
void ensure_rational_solution(simplex<mpq_ext>& s);
void kernel(sparse_matrix<mpq_ext>& s, vector<vector<rational>>& K);
};

View file

@ -143,6 +143,7 @@ namespace simplex {
svector<int> m_var_pos; // temporary map from variables to positions in row
unsigned_vector m_var_pos_idx; // indices in m_var_pos
stats m_stats;
scoped_numeral m_zero;
bool well_formed_row(unsigned row_id) const;
bool well_formed_column(unsigned column_id) const;
@ -151,7 +152,7 @@ namespace simplex {
public:
sparse_matrix(manager& _m): m(_m) {}
sparse_matrix(manager& _m): m(_m), m_zero(m) {}
~sparse_matrix();
void reset();
@ -208,41 +209,40 @@ namespace simplex {
row_iterator row_begin(row const& r) { return row_iterator(m_rows[r.id()], true); }
row_iterator row_end(row const& r) { return row_iterator(m_rows[r.id()], false); }
struct row_entries_t {
sparse_matrix& m;
row const& r;
row_entries_t(sparse_matrix & m, row const& r): m(m), r(r) {}
row_iterator begin() { return m.row_begin(r); }
row_iterator end() { return m.row_end(r); }
class row_vars {
friend class sparse_matrix;
sparse_matrix& s;
row r;
row_vars(sparse_matrix& s, row r): s(s), r(r) {}
public:
row_iterator begin() { return s.row_begin(r); }
row_iterator end() { return s.row_end(r); }
};
row_entries_t row_entries(row const& r) { return row_entries_t(*this, r); }
row_vars get_row(row r) { return row_vars(*this, r); }
unsigned column_size(var_t v) const { return m_columns[v].size(); }
unsigned num_vars() const { return m_columns.size(); }
unsigned num_rows() const { return m_rows.size(); }
class col_iterator {
friend class sparse_matrix;
unsigned m_curr;
int m_var;
sparse_matrix const& m_sm;
column const& col() const {
return m_sm.m_columns[m_var];
}
column const& m_col;
vector<_row>& m_rows;
void move_to_used() {
while (m_curr < col().num_entries() && col().m_entries[m_curr].is_dead()) {
++m_curr;
}
}
col_iterator(int var, sparse_matrix const& sm, bool begin):
m_curr(0), m_var(var), m_sm(sm) {
++col().m_refs;
if (begin)
col_iterator(column const& c, vector<_row>& r, bool begin):
m_curr(0), m_col(c), m_rows(r) {
++m_col.m_refs;
if (begin)
move_to_used();
else
m_curr = col().num_entries();
m_curr = m_col.num_entries();
}
public:
@ -255,18 +255,20 @@ namespace simplex {
m_curr(other.m_curr),
m_var(other.m_var),
m_sm(other.m_sm) {
++col().m_refs;
++m_col.m_refs;
}
row get_row() const {
return row(col().m_entries[m_curr].m_row_id);
return row(m_col.m_entries[m_curr].m_row_id);
}
row_entry const& get_row_entry() const {
col_entry const& c = col().m_entries[m_curr];
row_entry& get_row_entry() {
col_entry const& c = m_col.m_entries[m_curr];
int row_id = c.m_row_id;
return m_sm.m_rows[row_id].m_entries[c.m_row_idx];
}
std::pair<row, row_entry*> operator*() { return std::make_pair(get_row(), &get_row_entry()); }
col_iterator & operator++() { ++m_curr; move_to_used(); return *this; }
col_iterator operator++(int) { col_iterator tmp = *this; ++*this; return tmp; }
bool operator==(col_iterator const & it) const { return m_curr == it.m_curr; }
@ -274,24 +276,67 @@ namespace simplex {
col_iterator& operator*() { return *this; }
};
col_iterator col_begin(int v) const { return col_iterator(v, *this, true); }
col_iterator col_end(int v) const { return col_iterator(v, *this, false); }
col_iterator col_begin(int v) { return col_iterator(m_columns[v], m_rows, true); }
col_iterator col_end(int v) { return col_iterator(m_columns[v], m_rows, false); }
class col_entries_t {
sparse_matrix const& m;
class var_rows {
friend class sparse_matrix;
sparse_matrix& s;
int v;
var_rows(sparse_matrix& s, int v):s(s), v(v) {}
public:
col_entries_t(sparse_matrix const& m, int v): m(m), v(v) {}
col_iterator begin() { return m.col_begin(v); }
col_iterator end() { return m.col_end(v); }
col_iterator begin() { return s.col_begin(v); }
col_iterator end() { return s.col_end(v); }
};
var_rows get_rows(int v) { return var_rows(*this, v); }
class all_row_iterator {
friend class sparse_matrix;
unsigned m_curr;
vector<_row> const& m_rows;
void move_to_next() {
while (m_curr < m_rows.size() && m_rows[m_curr].size() == 0) {
//std::cout << "size is 0 for " << m_curr << "\n";
++m_curr;
}
}
public:
all_row_iterator(unsigned curr, vector<_row> const& rows): m_curr(curr), m_rows(rows) {
move_to_next();
}
row operator*() { return row(m_curr); }
all_row_iterator & operator++() { m_curr++; move_to_next(); return *this; }
all_row_iterator operator++(int) { all_row_iterator tmp = *this; ++*this; return tmp; }
bool operator==(all_row_iterator const& it) const { return m_curr == it.m_curr; }
bool operator!=(all_row_iterator const& it) const { return m_curr != it.m_curr; }
};
class all_rows {
friend class sparse_matrix;
sparse_matrix& s;
all_rows(sparse_matrix& s): s(s) {}
public:
all_row_iterator begin() { return all_row_iterator(0, s.m_rows); }
all_row_iterator end() { return all_row_iterator(s.m_rows.size(), s.m_rows); }
};
col_entries_t col_entries(int v) { return col_entries_t(*this, v); }
all_rows get_rows() { return all_rows(*this); }
numeral const& get_coeff(row r, unsigned v) {
for (auto & row : get_row(r))
if (row.m_var == v)
return row.m_coeff;
return m_zero;
}
void display(std::ostream& out);
void display_row(std::ostream& out, row const& r) const;
bool well_formed() const;
manager& get_manager() { return m; }
void collect_statistics(::statistics & st) const;
};
@ -312,4 +357,4 @@ namespace simplex {
typedef unsynch_mpq_inf_manager eps_manager;
};
};
}

View file

@ -298,6 +298,8 @@ namespace simplex {
template<typename Ext>
void sparse_matrix<Ext>::add_var(row dst, numeral const& n, var_t v) {
if (m.is_zero(n))
return;
_row& r = m_rows[dst.id()];
column& c = m_columns[v];
unsigned r_idx;
@ -316,6 +318,9 @@ namespace simplex {
*/
template<typename Ext>
void sparse_matrix<Ext>::add(row row1, numeral const& n, row row2) {
if (m.is_zero(n))
return;
m_stats.m_add_rows++;
_row & r1 = m_rows[row1.id()];

View file

@ -0,0 +1,85 @@
/*++
Copyright (c) 2014 Microsoft Corporation
Module Name:
sparse_matrix_ops.h
Abstract:
Author:
Nikolaj Bjorner (nbjorner) 2014-01-15
Notes:
--*/
#pragma once
#include "math/simplex/sparse_matrix.h"
#include "util/rational.h"
namespace simplex {
class sparse_matrix_ops {
public:
template <typename Ext>
static void kernel(sparse_matrix<Ext> &M, vector<vector<rational>> &K) {
using scoped_numeral = typename Ext::scoped_numeral;
vector<unsigned> d, c;
unsigned n_vars = M.num_vars(), n_rows = M.num_rows();
c.resize(n_rows, 0u);
d.resize(n_vars, 0u);
auto &m = M.get_manager();
scoped_numeral m_ik(m);
scoped_numeral D(m);
for (unsigned k = 0; k < n_vars; ++k) {
d[k] = 0;
for (auto [row, row_entry] : M.get_rows(k)) {
if (c[row.id()] != 0) continue;
auto &m_jk = row_entry->m_coeff;
if (mpq_manager<false>::is_zero(m_jk)) continue;
// D = rational(-1) / m_jk;
m.set(D, m_jk);
m.inv(D);
m.neg(D);
M.mul(row, D);
for (auto [row_i, row_i_entry] : M.get_rows(k)) {
if (row_i.id() == row.id()) continue;
m.set(m_ik, row_i_entry->m_coeff);
// row_i += m_ik * row
M.add(row_i, m_ik, row);
}
c[row.id()] = k + 1;
d[k] = row.id() + 1;
break;
}
}
for (unsigned k = 0; k < n_vars; ++k) {
if (d[k] != 0) continue;
K.push_back(vector<rational>());
for (unsigned i = 0; i < n_vars; ++i) {
if (d[i] > 0) {
auto r = sparse_matrix<mpq_ext>::row(d[i] - 1);
K.back().push_back(rational(M.get_coeff(r, k)));
} else if (i == k)
K.back().push_back(rational(1));
else
K.back().push_back(rational(0));
}
}
}
static void kernel(sparse_matrix<mpq_ext> &M, vector<vector<rational>> &K) {
kernel<mpq_ext>(M, K);
}
};
} // namespace simplex