3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-18 06:39:02 +00:00
Signed-off-by: Lev <levnach@hotmail.com>
This commit is contained in:
Lev 2018-10-06 15:51:06 -07:00 committed by Lev Nachmanson
parent 1ed9639898
commit 2fd32ce62d
6 changed files with 99 additions and 133 deletions

View file

@ -169,8 +169,6 @@ unsigned int_solver::row_of_basic_column(unsigned j) const {
// }
typedef monomial mono;
// this will allow to enable and disable tracking of the pivot rows
struct check_return_helper {

View file

@ -3,8 +3,9 @@
Author: Nikolaj Bjorner
*/
#include "util/lp/lar_solver.h"
#include "util/lp/mon_eq.h"
namespace nra {
#include "util/lp/monomial.h"
namespace nla {
typedef monomial mon_eq;
bool check_assignment(mon_eq const& m, variable_map_type & vars) {
rational r1 = vars[m.var()];
if (r1.is_zero()) {

View file

@ -1,60 +0,0 @@
/*
Copyright (c) 2017 Microsoft Corporation
Author: Nikolaj Bjorner
*/
#include "util/lp/lp_settings.h"
#include "util/vector.h"
#include "util/lp/lar_solver.h"
namespace nra {
/*
* represents definition m_v = v1*v2*...*vn,
* where m_vs = [v1, v2, .., vn]
*/
class mon_eq {
// fields
lp::var_index m_v;
svector<lp::var_index> m_vs;
public:
// constructors
mon_eq(lp::var_index v, unsigned sz, lp::var_index const* vs):
m_v(v), m_vs(sz, vs) {}
mon_eq(lp::var_index v, const svector<lp::var_index> &vs):
m_v(v), m_vs(vs) {}
mon_eq() {}
unsigned var() const { return m_v; }
unsigned size() const { return m_vs.size(); }
unsigned operator[](unsigned idx) const { return m_vs[idx]; }
svector<lp::var_index>::const_iterator begin() const { return m_vs.begin(); }
svector<lp::var_index>::const_iterator end() const { return m_vs.end(); }
const svector<lp::var_index> vars() const { return m_vs; }
};
typedef std::unordered_map<lp::var_index, rational> variable_map_type;
bool check_assignment(mon_eq const& m, variable_map_type & vars);
bool check_assignments(const vector<mon_eq> & monomimials,
const lp::lar_solver& s,
variable_map_type & vars);
/*
* represents definition m_v = coeff* v1*v2*...*vn,
* where m_vs = [v1, v2, .., vn]
*/
class mon_eq_coeff : public mon_eq {
rational m_coeff;
public:
mon_eq_coeff(mon_eq const& eq, rational const& coeff):
mon_eq(eq), m_coeff(coeff) {}
mon_eq_coeff(lp::var_index v, const svector<lp::var_index> &vs, rational const& coeff):
mon_eq(v, vs),
m_coeff(coeff) {}
rational const& coeff() const { return m_coeff; }
};
}

View file

@ -1,33 +1,60 @@
/*++
Copyright (c) 2017 Microsoft Corporation
/*
Copyright (c) 2017 Microsoft Corporation
Author: Nikolaj Bjorner
*/
#include "util/lp/lp_settings.h"
#include "util/vector.h"
#include "util/lp/lar_solver.h"
Module Name:
namespace nla {
/*
* represents definition m_v = v1*v2*...*vn,
* where m_vs = [v1, v2, .., vn]
*/
class monomial {
// fields
lp::var_index m_v;
svector<lp::var_index> m_vs;
public:
// constructors
monomial(lp::var_index v, unsigned sz, lp::var_index const* vs):
m_v(v), m_vs(sz, vs) {}
monomial(lp::var_index v, const svector<lp::var_index> &vs):
m_v(v), m_vs(vs) {}
monomial() {}
unsigned var() const { return m_v; }
unsigned size() const { return m_vs.size(); }
unsigned operator[](unsigned idx) const { return m_vs[idx]; }
svector<lp::var_index>::const_iterator begin() const { return m_vs.begin(); }
svector<lp::var_index>::const_iterator end() const { return m_vs.end(); }
const svector<lp::var_index> vars() const { return m_vs; }
};
<name>
Abstract:
<abstract>
Author:
Nikolaj Bjorner (nbjorner)
Lev Nachmanson (levnach)
Revision History:
typedef std::unordered_map<lp::var_index, rational> variable_map_type;
bool check_assignment(monomial const& m, variable_map_type & vars);
bool check_assignments(const vector<monomial> & monomimials,
const lp::lar_solver& s,
variable_map_type & vars);
--*/
#pragma once
namespace lp {
struct monomial {
mpq m_coeff; // the coefficient of the monomial
var_index m_var; // the variable index
public:
monomial(const mpq& coeff, var_index var) : m_coeff(coeff), m_var(var) {}
monomial(var_index var) : monomial(one_of_type<mpq>(), var) {}
const mpq & coeff() const { return m_coeff; }
mpq & coeff() { return m_coeff; }
var_index var() const { return m_var; }
std::pair<mpq, var_index> to_pair() const { return std::make_pair(coeff(), var());}
};
/*
* represents definition m_v = coeff* v1*v2*...*vn,
* where m_vs = [v1, v2, .., vn]
*/
class monomial_coeff : public monomial {
rational m_coeff;
public:
monomial_coeff(monomial const& eq, rational const& coeff):
monomial(eq), m_coeff(coeff) {}
monomial_coeff(lp::var_index v, const svector<lp::var_index> &vs, rational const& coeff):
monomial(v, vs),
m_coeff(coeff) {}
rational const& coeff() const { return m_coeff; }
};
}

View file

@ -19,12 +19,11 @@
--*/
#include "util/lp/nla_solver.h"
#include "util/map.h"
#include "util/lp/mon_eq.h"
#include "util/lp/monomial.h"
#include "util/lp/lp_utils.h"
namespace nla {
typedef lp::constraint_index lpci;
typedef std::unordered_set<lpci> expl_set;
typedef nra::mon_eq mon_eq;
typedef lp::var_index lpvar;
struct hash_svector {
@ -170,7 +169,7 @@ struct solver::imp {
};
vars_equivalence m_vars_equivalence;
vector<mon_eq> m_monomials;
vector<monomial> m_monomials;
// maps the vector of the rooted monomial vars to the list of the indices of monomials having the same rooted monomial
std::unordered_map<svector<lpvar>, vector<mono_index_with_sign>, hash_svector>
m_rooted_monomials;
@ -178,7 +177,7 @@ struct solver::imp {
lp::lar_solver& m_lar_solver;
std::unordered_map<lpvar, unsigned_vector> m_var_to_mon_indices;
// mon_eq.var() -> monomial index
// monomial.var() -> monomial index
u_map<unsigned> m_var_to_its_monomial;
lp::explanation * m_expl;
lemma * m_lemma;
@ -194,7 +193,7 @@ struct solver::imp {
lp::impq vv(unsigned j) const { return m_lar_solver.get_column_value(j); }
void add(lpvar v, unsigned sz, lpvar const* vs) {
m_monomials.push_back(mon_eq(v, sz, vs));
m_monomials.push_back(monomial(v, sz, vs));
m_var_to_its_monomial.insert(v, m_monomials.size() - 1);
}
@ -209,7 +208,7 @@ struct solver::imp {
}
// make sure that the monomial value is the product of the values of the factors
bool check_monomial(const mon_eq& m) {
bool check_monomial(const monomial& m) {
SASSERT(m_lar_solver.get_column_value(m.var()).is_int());
const rational & model_val = m_lar_solver.get_column_value_rational(m.var());
rational r(1);
@ -228,7 +227,7 @@ struct solver::imp {
return sign * m_lar_solver.get_column_value(j) != m_lar_solver.get_column_value(k);
}
void add_explanation_of_reducing_to_rooted_monomial(const mon_eq& m, expl_set & exp) const {
void add_explanation_of_reducing_to_rooted_monomial(const monomial& m, expl_set & exp) const {
m_vars_equivalence.add_explanation_of_reducing_to_rooted_monomial(m, exp);
}
@ -239,7 +238,7 @@ struct solver::imp {
add_explanation_of_reducing_to_rooted_monomial(m_monomials[index], exp);
}
std::ostream& print_monomial(const mon_eq& m, std::ostream& out) const {
std::ostream& print_monomial(const monomial& m, std::ostream& out) const {
out << m_lar_solver.get_variable_name(m.var()) << " = ";
for (unsigned k = 0; k < m.size(); k++) {
out << m_lar_solver.get_variable_name(m.vars()[k]);
@ -257,7 +256,7 @@ struct solver::imp {
// the monomials should be equal by modulo sign, but they are not equal in the model by modulo sign
void fill_explanation_and_lemma_sign(const mon_eq& a, const mon_eq & b, rational const& sign) {
void fill_explanation_and_lemma_sign(const monomial& a, const monomial & b, rational const& sign) {
expl_set expl;
SASSERT(sign == 1 || sign == -1);
add_explanation_of_reducing_to_rooted_monomial(a, expl);
@ -299,7 +298,7 @@ struct solver::imp {
// m_v = coeff * w1 * ... * wn, where w1, .., wn are canonical
// representative under current equations.
//
nra::mon_eq_coeff canonize_mon_eq(mon_eq const& m) const {
monomial_coeff canonize_monomial(monomial const& m) const {
svector<lpvar> vars;
rational sign = rational(1);
for (lpvar v : m.vars()) {
@ -308,7 +307,7 @@ struct solver::imp {
vars.push_back(root);
}
std::sort(vars.begin(), vars.end());
return nra::mon_eq_coeff(m.var(), vars, sign);
return monomial_coeff(m.var(), vars, sign);
}
bool list_contains_one_to_refine(const std::unordered_set<unsigned> & to_refine_set,
@ -424,7 +423,7 @@ struct solver::imp {
int get_mon_sign_zero(unsigned i_mon, bool & strict) {
int sign = 1;
strict = true;
const mon_eq m = m_monomials[i_mon];
const monomial m = m_monomials[i_mon];
for (lpvar j : m) {
int s = get_mon_sign_zero_var(j, strict);
if (s == 2)
@ -487,7 +486,7 @@ struct solver::imp {
return true;
}
void create_lemma_one_of_the_factors_is_zero(const mon_eq& m) {
void create_lemma_one_of_the_factors_is_zero(const monomial& m) {
lpci lci, uci;
rational b;
bool is_strict;
@ -526,16 +525,16 @@ struct solver::imp {
}
std::ostream & print_var(lpvar j, std::ostream & out) const {
bool monomial = false;
for (const mon_eq & m : m_monomials) {
bool is_monomial = false;
for (const monomial & m : m_monomials) {
if (j == m.var()) {
monomial = true;
is_monomial = true;
print_monomial(m, out);
out << " = " << m_lar_solver.get_column_value(j);;
break;
}
}
if (!monomial)
if (!is_monomial)
out << m_lar_solver.get_variable_name(j) << " = " << m_lar_solver.get_column_value(j);
out <<";";
return out;
@ -609,7 +608,7 @@ struct solver::imp {
}
void get_large_and_small_indices_of_monomimal(const mon_eq& m,
void get_large_and_small_indices_of_monomimal(const monomial& m,
unsigned_vector & large,
unsigned_vector & _small) {
@ -642,7 +641,7 @@ struct solver::imp {
* v is the value of monomial,
* vars is the array of reduced to minimum variables of the monomial
*/
bool basic_neutral_for_reduced_monomial(const mon_eq & m, const rational & v, const svector<lpvar> & vars) {
bool basic_neutral_for_reduced_monomial(const monomial & m, const rational & v, const svector<lpvar> & vars) {
vector<mono_index_with_sign> ones_of_mon = get_ones_of_monomimal(vars);
// if abs(m.vars()[j]) is 1, then ones_of_mon[j] = sign, where sign is 1 in case of m.vars()[j] = 1, or -1 otherwise.
@ -656,7 +655,7 @@ struct solver::imp {
* \brief <generate lemma by using the fact that 1*x = x or x*1 = x>
*/
bool basic_lemma_for_mon_neutral(unsigned i_mon) {
const mon_eq & m = m_monomials[i_mon];
const monomial & m = m_monomials[i_mon];
rational sign;
svector<lpvar> reduced_vars = reduce_monomial_to_canonical(m.vars(), sign);
rational v = m_lar_solver.get_column_value_rational(m.var());
@ -666,7 +665,7 @@ struct solver::imp {
}
// returns the variable m_i, of a monomial if found and sets the sign,
bool find_monomial_of_vars(const svector<lpvar>& vars, mon_eq& m, rational & sign) const {
bool find_monomial_of_vars(const svector<lpvar>& vars, monomial& m, rational & sign) const {
auto it = m_rooted_monomials.find(vars);
if (it == m_rooted_monomials.end()) {
return false;
@ -679,7 +678,7 @@ struct solver::imp {
}
bool find_complimenting_monomial(const svector<lpvar> & vars, lpvar & j) {
mon_eq m;
monomial m;
rational other_sign;
if (!find_monomial_of_vars(vars, m, other_sign)) {
return false;
@ -689,13 +688,13 @@ struct solver::imp {
}
bool find_lpvar_and_sign_with_wrong_val(
const mon_eq& m,
const monomial& m,
svector<lpvar> & vars,
const rational& v,
rational sign,
lpvar& j) {
rational other_sign;
mon_eq mn;
monomial mn;
if (!find_monomial_of_vars(vars, mn, other_sign)) {
return false;
}
@ -715,7 +714,7 @@ struct solver::imp {
// sign ?
// j ?
//
void equality_for_neutral_case(const mon_eq & m,
void equality_for_neutral_case(const monomial & m,
const svector<bool> & mask,
const vector<mono_index_with_sign>& ones_of_monomial, lpvar j, rational const& sign) {
expl_set expl;
@ -735,7 +734,7 @@ struct solver::imp {
}
// vars here are root vars for m.vs
bool process_ones_of_mon(const mon_eq& m,
bool process_ones_of_mon(const monomial& m,
const vector<mono_index_with_sign>& ones_of_monomial, const svector<lpvar> &min_vars,
const rational& v) {
svector<bool> mask(ones_of_monomial.size(), false);
@ -793,7 +792,7 @@ struct solver::imp {
expl.insert(ci);
}
void large_lemma_for_proportion_case_on_known_signs(const mon_eq& m,
void large_lemma_for_proportion_case_on_known_signs(const monomial& m,
unsigned j,
int mon_sign,
int j_sign) {
@ -818,7 +817,7 @@ struct solver::imp {
m_lemma->push_back(ineq(lp::lconstraint_kind::GE, t, rational::zero()));
}
bool large_lemma_for_proportion_case(const mon_eq& m, const svector<bool> & mask,
bool large_lemma_for_proportion_case(const monomial& m, const svector<bool> & mask,
const unsigned_vector & large, unsigned j) {
TRACE("nla_solver", );
const rational j_val = m_lar_solver.get_column_value_rational(j);
@ -842,7 +841,7 @@ struct solver::imp {
return true;
}
bool small_lemma_for_proportion_case(const mon_eq& m, const svector<bool> & mask,
bool small_lemma_for_proportion_case(const monomial& m, const svector<bool> & mask,
const unsigned_vector & _small, unsigned j) {
TRACE("nla_solver", );
const rational j_val = m_lar_solver.get_column_value_rational(j);
@ -868,7 +867,7 @@ struct solver::imp {
}
// It is the case where |x[j]| >= |x[m.var()]| should hold in the model, but it does not.
void small_lemma_for_proportion_case_on_known_signs(const mon_eq& m, unsigned j, int mon_sign, int j_sign) {
void small_lemma_for_proportion_case_on_known_signs(const monomial& m, unsigned j, int mon_sign, int j_sign) {
// Imagine that the signs are all positive.
// For this case we would have x[j] < 0 || x[m.var()] < 0 || x[j] >= x[m.var()]
// But for the general case we have
@ -954,7 +953,7 @@ struct solver::imp {
// we derive a lemma from |x| >= 1 => |xy| >= |y| or |x| <= 1 => |xy| <= |y|
bool basic_lemma_for_mon_proportionality_from_factors_to_product(unsigned i_mon) {
const mon_eq & m = m_monomials[i_mon];
const monomial & m = m_monomials[i_mon];
unsigned_vector large;
unsigned_vector _small;
get_large_and_small_indices_of_monomimal(m, large, _small);
@ -1009,14 +1008,14 @@ struct solver::imp {
struct binary_factorizations_of_monomial {
unsigned m_i_mon;
const imp& m_imp;
const mon_eq& m_mon;
nra::mon_eq_coeff m_cmon;
const monomial& m_mon;
monomial_coeff m_cmon;
binary_factorizations_of_monomial(unsigned i_mon, const imp& s) :
m_i_mon(i_mon),
m_imp(s),
m_mon(m_imp.m_monomials[i_mon]),
m_cmon(m_imp.canonize_mon_eq(m_mon)) {
m_cmon(m_imp.canonize_monomial(m_mon)) {
}
@ -1056,7 +1055,7 @@ struct solver::imp {
std::sort(j_vars.begin(), j_vars.end());
rational k_sign, j_sign;
mon_eq m;
monomial m;
if (k_vars.size() == 1) {
k = k_vars[0];
k_sign = 1;
@ -1391,7 +1390,7 @@ struct solver::imp {
}
void map_monomial_vars_to_monomial_indices(unsigned i) {
const mon_eq& m = m_monomials[i];
const monomial& m = m_monomials[i];
for (lpvar j : m.vars()) {
auto it = m_var_to_mon_indices.find(j);
if (it == m_var_to_mon_indices.end()) {
@ -1459,7 +1458,7 @@ struct solver::imp {
m_vars_equivalence.create_tree();
}
void register_key_mono_in_min_monomials(nra::mon_eq_coeff const& mc, unsigned i) {
void register_key_mono_in_min_monomials(monomial_coeff const& mc, unsigned i) {
mono_index_with_sign ms(i, mc.coeff());
auto it = m_rooted_monomials.find(mc.vars());
@ -1475,8 +1474,8 @@ struct solver::imp {
}
void register_monomial_in_min_map(unsigned i) {
const mon_eq& m = m_monomials[i];
nra::mon_eq_coeff mc = canonize_mon_eq(m_monomials[i]);
const monomial& m = m_monomials[i];
monomial_coeff mc = canonize_monomial(m_monomials[i]);
register_key_mono_in_min_monomials(mc, i);
}

View file

@ -9,11 +9,12 @@
#include "math/polynomial/polynomial.h"
#include "math/polynomial/algebraic_numbers.h"
#include "util/map.h"
#include "util/lp/mon_eq.h"
#include "util/lp/monomial.h"
namespace nra {
typedef nla::monomial mon_eq;
typedef nla::variable_map_type variable_map_type;
struct solver::imp {
lp::lar_solver& s;
reslimit& m_limit;