mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 05:18:44 +00:00
191 lines
4.5 KiB
C++
191 lines
4.5 KiB
C++
|
|
/*++
|
|
Copyright (c) 2015 Microsoft Corporation
|
|
|
|
--*/
|
|
|
|
#include "math/simplex/sparse_matrix_def.h"
|
|
#include "math/simplex/simplex.h"
|
|
#include "math/simplex/simplex_def.h"
|
|
#include "util/mpq_inf.h"
|
|
#include "util/vector.h"
|
|
#include "util/rational.h"
|
|
#include "util/rlimit.h"
|
|
|
|
#define R rational
|
|
typedef simplex::simplex<simplex::mpz_ext> Simplex;
|
|
typedef simplex::sparse_matrix<simplex::mpz_ext> sparse_matrix;
|
|
typedef simplex::sparse_matrix<simplex::mpq_ext> qmatrix;
|
|
|
|
static vector<R> vec(int i, int j) {
|
|
vector<R> nv;
|
|
nv.resize(2);
|
|
nv[0] = R(i);
|
|
nv[1] = R(j);
|
|
return nv;
|
|
}
|
|
|
|
static vector<R> vec(int i, int j, int k) {
|
|
vector<R> nv = vec(i, j);
|
|
nv.push_back(R(k));
|
|
return nv;
|
|
}
|
|
|
|
// static vector<R> vec(int i, int j, int k, int l) {
|
|
// vector<R> nv = vec(i, j, k);
|
|
// nv.push_back(R(l));
|
|
// return nv;
|
|
// }
|
|
|
|
/// static vector<R> vec(int i, int j, int k, int l, int x) {
|
|
/// vector<R> nv = vec(i, j, k, l);
|
|
/// nv.push_back(R(x));
|
|
/// return nv;
|
|
/// }
|
|
|
|
// static vector<R> vec(int i, int j, int k, int l, int x, int y) {
|
|
// vector<R> nv = vec(i, j, k, l, x);
|
|
// nv.push_back(R(y));
|
|
// return nv;
|
|
// }
|
|
|
|
// static vector<R> vec(int i, int j, int k, int l, int x, int y, int z) {
|
|
// vector<R> nv = vec(i, j, k, l, x, y);
|
|
// nv.push_back(R(z));
|
|
// return nv;
|
|
// }
|
|
|
|
|
|
|
|
void add_row(Simplex& S, vector<R> const& _v, R const& _b, bool is_eq = false) {
|
|
unsynch_mpz_manager m;
|
|
unsigned_vector vars;
|
|
vector<R> v(_v);
|
|
R b(_b);
|
|
R l(denominator(b));
|
|
scoped_mpz_vector coeffs(m);
|
|
for (unsigned i = 0; i < v.size(); ++i) {
|
|
l = lcm(l, denominator(v[i]));
|
|
vars.push_back(i);
|
|
S.ensure_var(i);
|
|
}
|
|
b *= l;
|
|
b.neg();
|
|
for (unsigned i = 0; i < v.size(); ++i) {
|
|
v[i] *= l;
|
|
coeffs.push_back(v[i].to_mpq().numerator());
|
|
}
|
|
unsigned nv = S.get_num_vars();
|
|
vars.push_back(nv);
|
|
vars.push_back(nv+1);
|
|
S.ensure_var(nv);
|
|
S.ensure_var(nv+1);
|
|
coeffs.push_back(mpz(-1));
|
|
coeffs.push_back(b.to_mpq().numerator());
|
|
mpq_inf one(mpq(1),mpq(0));
|
|
mpq_inf zero(mpq(0),mpq(0));
|
|
ENSURE(vars.size() == coeffs.size());
|
|
S.set_lower(nv, zero);
|
|
if (is_eq) S.set_upper(nv, zero);
|
|
S.set_lower(nv+1, one);
|
|
S.set_upper(nv+1, one);
|
|
S.add_row(nv, coeffs.size(), vars.data(), coeffs.data());
|
|
}
|
|
|
|
static void feas(Simplex& S) {
|
|
S.display(std::cout);
|
|
lbool is_sat = S.make_feasible();
|
|
std::cout << "feasible: " << is_sat << "\n";
|
|
S.display(std::cout);
|
|
}
|
|
|
|
static void test1() {
|
|
reslimit rl;
|
|
Simplex S(rl);
|
|
add_row(S, vec(1,0), R(1));
|
|
add_row(S, vec(0,1), R(1));
|
|
add_row(S, vec(1,1), R(1));
|
|
feas(S);
|
|
}
|
|
|
|
static void test2() {
|
|
reslimit rl; Simplex S(rl);
|
|
add_row(S, vec(1, 0), R(1));
|
|
add_row(S, vec(0, 1), R(1));
|
|
add_row(S, vec(1, 1), R(1), true);
|
|
feas(S);
|
|
}
|
|
|
|
static void test3() {
|
|
reslimit rl; Simplex S(rl);
|
|
add_row(S, vec(-1, 0), R(-1));
|
|
add_row(S, vec(0, -1), R(-1));
|
|
add_row(S, vec(1, 1), R(1), true);
|
|
feas(S);
|
|
}
|
|
|
|
static void test4() {
|
|
reslimit rl; Simplex S(rl);
|
|
add_row(S, vec(1, 0), R(1));
|
|
add_row(S, vec(0, -1), R(-1));
|
|
add_row(S, vec(1, 1), R(1), true);
|
|
feas(S);
|
|
}
|
|
|
|
static void add(qmatrix& m, vector<R> const& v) {
|
|
m.ensure_var(v.size());
|
|
auto r = m.mk_row();
|
|
for (unsigned u = 0; u < v.size(); ++u)
|
|
m.add_var(r, v[u].to_mpq(), u);
|
|
}
|
|
|
|
static void test5() {
|
|
unsynch_mpq_manager m;
|
|
qmatrix M(m);
|
|
add(M, vec(1, 2, 3));
|
|
add(M, vec(2, 2, 4));
|
|
M.display(std::cout);
|
|
gauss_jordan(M);
|
|
std::cout << "after\n";
|
|
M.display(std::cout);
|
|
|
|
}
|
|
|
|
void tst_simplex() {
|
|
reslimit rl; Simplex S(rl);
|
|
|
|
std::cout << "simplex\n";
|
|
|
|
lbool is_sat = S.make_feasible();
|
|
std::cout << "feasible: " << is_sat << "\n";
|
|
|
|
unsynch_mpz_manager m;
|
|
unsynch_mpq_inf_manager em;
|
|
scoped_mpz_vector coeffs(m);
|
|
svector<unsigned> vars;
|
|
for (unsigned i = 0; i < 5; ++i) {
|
|
S.ensure_var(i);
|
|
vars.push_back(i);
|
|
coeffs.push_back(mpz(i+1));
|
|
}
|
|
|
|
// Simplex::row r = S.add_row(1, coeffs.size(), vars.c_ptr(), coeffs.c_ptr());
|
|
is_sat = S.make_feasible();
|
|
std::cout << "feasible: " << is_sat << "\n";
|
|
S.display(std::cout);
|
|
_scoped_numeral<unsynch_mpq_inf_manager> num(em);
|
|
num = std::make_pair(mpq(1), mpq(0));
|
|
S.set_lower(0, num);
|
|
S.set_upper(0, num);
|
|
|
|
is_sat = S.make_feasible();
|
|
std::cout << "feasible: " << is_sat << "\n";
|
|
S.display(std::cout);
|
|
|
|
test1();
|
|
test2();
|
|
test3();
|
|
test4();
|
|
test5();
|
|
}
|