3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-04 02:10:23 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2022-05-10 07:42:32 -07:00
parent 6a8ac5f9b1
commit 0557d72d1c
4 changed files with 32 additions and 16 deletions

View file

@ -37,7 +37,7 @@ namespace simplex {
} }
} }
void kernel(sparse_matrix<mpq_ext>& M, vector<vector<mpq>>& K) { void kernel(sparse_matrix<mpq_ext>& M, vector<vector<rational>>& K) {
sparse_matrix_ops::kernel(M, K); sparse_matrix_ops::kernel(M, K);
} }

View file

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

View file

@ -25,45 +25,60 @@ namespace simplex {
class sparse_matrix_ops { class sparse_matrix_ops {
public: public:
static void kernel(sparse_matrix<mpq_ext>& M, vector<vector<mpq>>& K) { static void kernel(sparse_matrix<mpq_ext>& M, vector<vector<rational>>& K) {
mpq_ext::numeral coeff; mpq_ext::numeral coeff;
vector<unsigned> d; rational D1, D2;
bool_vector c; vector<unsigned> d, c;
unsigned m = M.num_vars(); unsigned m = M.num_vars();
auto& mgr = M.get_manager();
for (unsigned v = 0; v < m; ++v) for (unsigned v = 0; v < m; ++v)
c.push_back(false); c.push_back(0);
for (auto const& row : M.get_rows()) { for (auto const& row : M.get_rows()) {
// scan for non-zero variable in row // scan for non-zero variable in row
bool found = false; bool found = false;
d.push_back(0); d.push_back(0);
for (auto const& [coeff1, v] : M.get_row(row)) { for (auto& [coeff1, v] : M.get_row(row)) {
if (mpq_manager<false>::is_zero(coeff1)) if (mpq_manager<false>::is_zero(coeff1))
continue; continue;
if (c[v]) if (c[v] != 0)
continue; continue;
d.back() = v + 1; d.back() = v + 1;
c[v] = true; c[v] = row.id() + 1;
D1 = rational(-1) / coeff1;
mgr.set(coeff1, mpq(-1));
// eliminate v from other rows. // eliminate v from other rows.
for (auto const& [row2, row_entry2] : M.get_rows(v)) { for (auto const& [row2, row_entry2] : M.get_rows(v)) {
if (row.id() == row2.id()) if (row.id() >= row2.id() || row_entry2->m_coeff == 0)
continue; continue;
if (row_entry2->m_coeff == 0) for (auto& [coeff2, w] : M.get_row(row2)) {
if (v == w)
mgr.set(coeff2, (D1*coeff2).to_mpq());
}
}
for (auto& [coeff2, w] : M.get_row(row)) {
if (v == w)
continue; continue;
M.get_manager().set(coeff, (- row_entry2->m_coeff / coeff1).to_mpq()); D2 = coeff2;
M.add(row2, coeff, row); mgr.set(coeff2, mpq(0));
for (auto const& [row2, row_entry2] : M.get_rows(w)) {
if (row.id() >= row2.id() || row_entry2->m_coeff == 0 || row_entry2->m_var == v)
continue;
// mgr.set(row_entry2->m_coeff, row_entry2->m_coeff + D2*row2[v]);
}
} }
break; break;
} }
} }
M.get_manager().del(coeff); mgr.del(coeff);
// TODO: extract kernel using d // TODO: extract kernel using d
for (unsigned k = 0; k < d.size(); ++k) { for (unsigned k = 0; k < d.size(); ++k) {
if (d[k] != 0) if (d[k] != 0)
continue; continue;
K.push_back(vector<mpq>()); K.push_back(vector<rational>());
for (unsigned i = 0; i < d.size(); ++i) { for (unsigned i = 0; i < d.size(); ++i) {
// K.back().push_back(d[i] > 0 ? M[d[i]-1][k] : (i == k) ? 1 : 0); // K.back().push_back(d[i] > 0 ? M[d[i]-1][k] : (i == k) ? 1 : 0);
} }

View file

@ -145,7 +145,7 @@ static void test5() {
add(M, vec(1, 2, 3)); add(M, vec(1, 2, 3));
add(M, vec(2, 2, 4)); add(M, vec(2, 2, 4));
M.display(std::cout); M.display(std::cout);
vector<vector<mpq>> K; vector<vector<rational>> K;
kernel(M, K); kernel(M, K);
std::cout << "after\n"; std::cout << "after\n";
M.display(std::cout); M.display(std::cout);