3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-13 12:28:44 +00:00

rename monomial to monic

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2019-09-17 14:31:09 -07:00
parent cc5a12c5c7
commit a0bdb8135d
30 changed files with 481 additions and 479 deletions

View file

@ -26,29 +26,29 @@
namespace nla {
void emonomials::inc_visited() const {
void emonics::inc_visited() const {
++m_visited;
if (m_visited == 0) {
for (auto& svt : m_monomials) {
for (auto& svt : m_monics) {
svt.visited() = 0;
}
++m_visited;
}
}
void emonomials::push() {
void emonics::push() {
m_u_f_stack.push_scope();
m_lim.push_back(m_monomials.size());
m_lim.push_back(m_monics.size());
m_region.push_scope();
m_ve.push();
SASSERT(monomials_are_canonized());
SASSERT(monics_are_canonized());
}
void emonomials::pop(unsigned n) {
void emonics::pop(unsigned n) {
m_ve.pop(n);
unsigned old_sz = m_lim[m_lim.size() - n];
for (unsigned i = m_monomials.size(); i-- > old_sz; ) {
monomial & m = m_monomials[i];
for (unsigned i = m_monics.size(); i-- > old_sz; ) {
monic & m = m_monics[i];
remove_cg_mon(m);
m_var2index[m.var()] = UINT_MAX;
lpvar last_var = UINT_MAX;
@ -59,15 +59,15 @@ void emonomials::pop(unsigned n) {
}
}
}
m_monomials.shrink(old_sz);
m_monomials.shrink(old_sz);
m_monics.shrink(old_sz);
m_monics.shrink(old_sz);
m_region.pop_scope(n);
m_lim.shrink(m_lim.size() - n);
SASSERT(monomials_are_canonized());
SASSERT(monics_are_canonized());
m_u_f_stack.pop_scope(n);
}
void emonomials::remove_cell(head_tail& v, unsigned mIndex) {
void emonics::remove_cell(head_tail& v, unsigned mIndex) {
cell*& cur_head = v.m_head;
cell*& cur_tail = v.m_tail;
cell* old_head = cur_head->m_next;
@ -81,7 +81,7 @@ void emonomials::remove_cell(head_tail& v, unsigned mIndex) {
}
}
void emonomials::insert_cell(head_tail& v, unsigned mIndex) {
void emonics::insert_cell(head_tail& v, unsigned mIndex) {
cell*& cur_head = v.m_head;
cell*& cur_tail = v.m_tail;
cell* new_head = new (m_region) cell(mIndex, cur_head);
@ -90,7 +90,7 @@ void emonomials::insert_cell(head_tail& v, unsigned mIndex) {
cur_tail->m_next = new_head;
}
void emonomials::merge_cells(head_tail& root, head_tail& other) {
void emonics::merge_cells(head_tail& root, head_tail& other) {
if (&root == &other) return;
cell*& root_head = root.m_head;
cell*& root_tail = root.m_tail;
@ -111,7 +111,7 @@ void emonomials::merge_cells(head_tail& root, head_tail& other) {
}
}
void emonomials::unmerge_cells(head_tail& root, head_tail& other) {
void emonics::unmerge_cells(head_tail& root, head_tail& other) {
if (&root == &other) return;
cell*& root_head = root.m_head;
cell*& root_tail = root.m_tail;
@ -131,26 +131,26 @@ void emonomials::unmerge_cells(head_tail& root, head_tail& other) {
}
}
emonomials::cell* emonomials::head(lpvar v) const {
emonics::cell* emonics::head(lpvar v) const {
v = m_ve.find(v).var();
m_use_lists.reserve(v + 1);
return m_use_lists[v].m_head;
}
monomial const* emonomials::find_canonical(svector<lpvar> const& vars) const {
monic const* emonics::find_canonical(svector<lpvar> const& vars) const {
SASSERT(m_ve.is_root(vars));
m_find_key = vars;
std::sort(m_find_key.begin(), m_find_key.end());
monomial const* result = nullptr;
monic const* result = nullptr;
lpvar w;
if (m_cg_table.find(UINT_MAX, w)) {
result = &m_monomials[m_var2index[w]];
result = &m_monics[m_var2index[w]];
}
return result;
}
void emonomials::remove_cg(lpvar v) {
void emonics::remove_cg(lpvar v) {
cell* c = m_use_lists[v].m_head;
if (c == nullptr) {
return;
@ -160,7 +160,7 @@ void emonomials::remove_cg(lpvar v) {
do {
unsigned idx = c->m_index;
c = c->m_next;
monomial & m = m_monomials[idx];
monic & m = m_monics[idx];
if (!is_visited(m)) {
set_visited(m);
remove_cg_mon(m);
@ -169,7 +169,7 @@ void emonomials::remove_cg(lpvar v) {
while (c != first);
}
void emonomials::remove_cg_mon(const monomial& m) {
void emonics::remove_cg_mon(const monic& m) {
lpvar u = m.var(), w;
// equivalence class of u:
if (m_cg_table.find(u, w)) {
@ -179,13 +179,13 @@ void emonomials::remove_cg_mon(const monomial& m) {
}
/**
\brief insert canonized monomials using v into a congruence table.
Prior to insertion, the monomials are canonized according to the current
variable equivalences. The canonized monomials (monomial) are considered
\brief insert canonized monics using v into a congruence table.
Prior to insertion, the monics are canonized according to the current
variable equivalences. The canonized monics (monic) are considered
in the same equivalence class if they have the same set of representative
variables. Their signs may differ.
*/
void emonomials::insert_cg(lpvar v) {
void emonics::insert_cg(lpvar v) {
cell* c = m_use_lists[v].m_head;
if (c == nullptr) {
@ -197,7 +197,7 @@ void emonomials::insert_cg(lpvar v) {
do {
unsigned idx = c->m_index;
c = c->m_next;
monomial & m = m_monomials[idx];
monic & m = m_monics[idx];
if (!is_visited(m)) {
set_visited(m);
insert_cg_mon(m);
@ -206,8 +206,8 @@ void emonomials::insert_cg(lpvar v) {
while (c != first);
}
bool emonomials::elists_are_consistent(std::unordered_map<unsigned_vector, std::unordered_set<lpvar>, hash_svector>& lists) const {
for (auto const & m : m_monomials) {
bool emonics::elists_are_consistent(std::unordered_map<unsigned_vector, std::unordered_set<lpvar>, hash_svector>& lists) const {
for (auto const & m : m_monics) {
auto it = lists.find(m.rvars());
if (it == lists.end()) {
std::unordered_set<lpvar> v;
@ -217,12 +217,12 @@ bool emonomials::elists_are_consistent(std::unordered_map<unsigned_vector, std::
it->second.insert(m.var());
}
}
for (auto const & m : m_monomials) {
for (auto const & m : m_monics) {
SASSERT(is_canonized(m));
if (!is_canonical_monomial(m.var()))
if (!is_canonical_monic(m.var()))
continue;
std::unordered_set<lpvar> c;
for (const monomial& e : enum_sign_equiv_monomials(m))
for (const monic& e : enum_sign_equiv_monics(m))
c.insert(e.var());
auto it = lists.find(m.rvars());
@ -244,7 +244,7 @@ bool emonomials::elists_are_consistent(std::unordered_map<unsigned_vector, std::
}
void emonomials::insert_cg_mon(monomial & m) {
void emonics::insert_cg_mon(monic & m) {
do_canonize(m);
lpvar v = m.var(), w;
if (m_cg_table.find(v, w)) {
@ -266,25 +266,25 @@ void emonomials::insert_cg_mon(monomial & m) {
}
}
void emonomials::set_visited(monomial& m) const {
m_monomials[m_var2index[m.var()]].visited() = m_visited;
void emonics::set_visited(monic& m) const {
m_monics[m_var2index[m.var()]].visited() = m_visited;
}
bool emonomials::is_visited(monomial const& m) const {
return m_visited == m_monomials[m_var2index[m.var()]].visited();
bool emonics::is_visited(monic const& m) const {
return m_visited == m_monics[m_var2index[m.var()]].visited();
}
/**
\brief insert a new monomial.
\brief insert a new monic.
Assume that the variables are canonical, that is, not equal in current
context to another variable. The monomial is inserted into a congruence
class of equal up-to var_eqs monomials.
context to another variable. The monic is inserted into a congruence
class of equal up-to var_eqs monics.
*/
void emonomials::add(lpvar v, unsigned sz, lpvar const* vs) {
void emonics::add(lpvar v, unsigned sz, lpvar const* vs) {
TRACE("nla_solver_mons", tout << "v = " << v << "\n";);
unsigned idx = m_monomials.size();
m_monomials.push_back(monomial(v, sz, vs, idx));
unsigned idx = m_monics.size();
m_monics.push_back(monic(v, sz, vs, idx));
lpvar last_var = UINT_MAX;
for (unsigned i = 0; i < sz; ++i) {
lpvar w = vs[i];
@ -297,10 +297,10 @@ void emonomials::add(lpvar v, unsigned sz, lpvar const* vs) {
}
SASSERT(m_ve.is_root(v));
m_var2index.setx(v, idx, UINT_MAX);
insert_cg_mon(m_monomials[idx]);
insert_cg_mon(m_monics[idx]);
}
void emonomials::do_canonize(monomial & m) const {
void emonics::do_canonize(monic & m) const {
m.reset_rfields();
for (lpvar v : m.vars()) {
m.push_rvar(m_ve.find(v));
@ -308,14 +308,14 @@ void emonomials::do_canonize(monomial & m) const {
m.sort_rvars();
}
bool emonomials::is_canonized(const monomial & m) const {
monomial mm(m);
bool emonics::is_canonized(const monic & m) const {
monic mm(m);
do_canonize(mm);
return mm.rvars() == m.rvars();
}
bool emonomials:: monomials_are_canonized() const {
for (auto & m: m_monomials) {
bool emonics:: monics_are_canonized() const {
for (auto & m: m_monics) {
if (! is_canonized(m)) {
return false;
}
@ -324,7 +324,7 @@ bool emonomials:: monomials_are_canonized() const {
}
bool emonomials::canonize_divides(monomial& m, monomial & n) const {
bool emonics::canonize_divides(monic& m, monic & n) const {
if (m.size() > n.size()) return false;
unsigned ms = m.size(), ns = n.size();
unsigned i = 0, j = 0;
@ -347,18 +347,18 @@ bool emonomials::canonize_divides(monomial& m, monomial & n) const {
}
}
// yes, assume that monomials are non-empty.
emonomials::pf_iterator::pf_iterator(emonomials const& m, monomial & mon, bool at_end):
// yes, assume that monics are non-empty.
emonics::pf_iterator::pf_iterator(emonics const& m, monic & mon, bool at_end):
m_em(m), m_mon(&mon), m_it(iterator(m, m.head(mon.vars()[0]), at_end)), m_end(iterator(m, m.head(mon.vars()[0]), true)) {
fast_forward();
}
emonomials::pf_iterator::pf_iterator(emonomials const& m, lpvar v, bool at_end):
emonics::pf_iterator::pf_iterator(emonics const& m, lpvar v, bool at_end):
m_em(m), m_mon(nullptr), m_it(iterator(m, m.head(v), at_end)), m_end(iterator(m, m.head(v), true)) {
fast_forward();
}
void emonomials::pf_iterator::fast_forward() {
void emonics::pf_iterator::fast_forward() {
for (; m_it != m_end; ++m_it) {
if (m_mon && m_mon->var() != (*m_it).var() && m_em.canonize_divides(*m_mon, *m_it) && !m_em.is_visited(*m_it)) {
m_em.set_visited(*m_it);
@ -371,11 +371,11 @@ void emonomials::pf_iterator::fast_forward() {
}
}
void emonomials::merge_eh(signed_var r2, signed_var r1, signed_var v2, signed_var v1) {
void emonics::merge_eh(signed_var r2, signed_var r1, signed_var v2, signed_var v1) {
// no-op
}
void emonomials::after_merge_eh(signed_var r2, signed_var r1, signed_var v2, signed_var v1) {
void emonics::after_merge_eh(signed_var r2, signed_var r1, signed_var v2, signed_var v1) {
TRACE("nla_solver_mons", tout << r2 << " <- " << r1 << "\n";);
if (m_ve.find(~r1) == m_ve.find(~r2)) { // the other sign has also been merged
m_use_lists.reserve(std::max(r2.var(), r1.var()) + 1);
@ -385,7 +385,7 @@ void emonomials::after_merge_eh(signed_var r2, signed_var r1, signed_var v2, sig
}
}
void emonomials::unmerge_eh(signed_var r2, signed_var r1) {
void emonics::unmerge_eh(signed_var r2, signed_var r1) {
TRACE("nla_solver_mons", tout << r2 << " -> " << r1 << "\n";);
if (m_ve.find(~r1) != m_ve.find(~r2)) { // the other sign has also been unmerged
unmerge_cells(m_use_lists[r2.var()], m_use_lists[r1.var()]);
@ -393,25 +393,25 @@ void emonomials::unmerge_eh(signed_var r2, signed_var r1) {
}
}
std::ostream& emonomials::display(const core& cr, std::ostream& out) const {
out << "monomials\n";
std::ostream& emonics::display(const core& cr, std::ostream& out) const {
out << "monics\n";
unsigned idx = 0;
for (auto const& m : m_monomials) {
for (auto const& m : m_monics) {
out << "m" << (idx++) << ": " << pp_mon_with_vars(cr, m) << "\n";
}
return display_use(out);
}
std::ostream& emonomials::display(std::ostream& out) const {
out << "monomials\n";
std::ostream& emonics::display(std::ostream& out) const {
out << "monics\n";
unsigned idx = 0;
for (auto const& m : m_monomials) {
for (auto const& m : m_monics) {
out << "m" << (idx++) << ": " << m << "\n";
}
return display_use(out);
}
std::ostream& emonomials::display_use(std::ostream& out) const {
std::ostream& emonics::display_use(std::ostream& out) const {
out << "use lists\n";
unsigned idx = 0;
for (auto const& ht : m_use_lists) {

View file

@ -22,7 +22,7 @@
#pragma once
#include "math/lp/lp_utils.h"
#include "math/lp/var_eqs.h"
#include "math/lp/monomial.h"
#include "math/lp/monic.h"
#include "util/region.h"
namespace nla {
@ -35,9 +35,9 @@ struct hash_svector {
class core;
class emonomials {
class emonics {
/**
\brief singly-lined cyclic list of monomial indices where variable occurs.
\brief singly-lined cyclic list of monic indices where variable occurs.
Each variable points to the head and tail of the cyclic list.
Initially, head and tail are nullptr.
New elements are inserted in the beginning of the list.
@ -55,11 +55,11 @@ class emonomials {
cell* m_tail;
};
struct hash_canonical {
emonomials& em;
hash_canonical(emonomials& em): em(em) {}
emonics& em;
hash_canonical(emonics& em): em(em) {}
unsigned operator()(lpvar v) const {
auto const& vec = v != UINT_MAX? em.m_monomials[em.m_var2index[v]].rvars() : em.m_find_key;
auto const& vec = v != UINT_MAX? em.m_monics[em.m_var2index[v]].rvars() : em.m_find_key;
return string_hash(reinterpret_cast<char const*>(vec.c_ptr()), sizeof(lpvar)*vec.size(), 10);
}
};
@ -67,29 +67,29 @@ class emonomials {
/**
\brief private fields used by emonomials for maintaining state of canonized monomials.
\brief private fields used by emonics for maintaining state of canonized monics.
*/
struct eq_canonical {
emonomials& em;
eq_canonical(emonomials& em): em(em) {}
emonics& em;
eq_canonical(emonics& em): em(em) {}
bool operator()(lpvar u, lpvar v) const {
auto const& uvec = u != UINT_MAX? em.m_monomials[em.m_var2index[u]].rvars(): em.m_find_key;
auto const& vvec = v != UINT_MAX? em.m_monomials[em.m_var2index[v]].rvars(): em.m_find_key;
auto const& uvec = u != UINT_MAX? em.m_monics[em.m_var2index[u]].rvars(): em.m_find_key;
auto const& vvec = v != UINT_MAX? em.m_monics[em.m_var2index[v]].rvars(): em.m_find_key;
return uvec == vvec;
}
};
union_find<emonomials> m_u_f;
trail_stack<emonomials> m_u_f_stack;
mutable svector<lpvar> m_find_key; // the key used when looking for a monomial with the specific variables
var_eqs<emonomials>& m_ve;
mutable vector<monomial> m_monomials; // set of monomials
union_find<emonics> m_u_f;
trail_stack<emonics> m_u_f_stack;
mutable svector<lpvar> m_find_key; // the key used when looking for a monic with the specific variables
var_eqs<emonics>& m_ve;
mutable vector<monic> m_monics; // set of monics
mutable unsigned_vector m_var2index; // var_mIndex -> mIndex
unsigned_vector m_lim; // backtracking point
mutable unsigned m_visited; // timestamp of visited monomials during pf_iterator
mutable unsigned m_visited; // timestamp of visited monics during pf_iterator
region m_region; // region for allocating linked lists
mutable svector<head_tail> m_use_lists; // use list of monomials where variables occur.
mutable svector<head_tail> m_use_lists; // use list of monics where variables occur.
hash_canonical m_cg_hash;
eq_canonical m_cg_eq;
hashtable<lpvar, hash_canonical, eq_canonical> m_cg_table; // congruence (canonical) table.
@ -104,23 +104,23 @@ class emonomials {
void remove_cg(lpvar v);
void insert_cg(lpvar v);
void insert_cg_mon(monomial & m);
void remove_cg_mon(const monomial & m);
void insert_cg_mon(monic & m);
void remove_cg_mon(const monic & m);
void rehash_cg(lpvar v) { remove_cg(v); insert_cg(v); }
void do_canonize(monomial& m) const;
void do_canonize(monic& m) const;
cell* head(lpvar v) const;
void set_visited(monomial& m) const;
bool is_visited(monomial const& m) const;
void set_visited(monic& m) const;
bool is_visited(monic const& m) const;
std::ostream& display_use(std::ostream& out) const;
public:
unsigned number_of_monomials() const { return m_monomials.size(); }
unsigned number_of_monics() const { return m_monics.size(); }
/**
\brief emonomials builds on top of var_eqs.
push and pop on emonomials calls push/pop on var_eqs, so no
\brief emonics builds on top of var_eqs.
push and pop on emonics calls push/pop on var_eqs, so no
other calls to push/pop to the var_eqs should take place.
*/
emonomials(var_eqs<emonomials>& ve):
emonics(var_eqs<emonics>& ve):
m_u_f(*this),
m_u_f_stack(*this),
m_ve(ve),
@ -139,7 +139,7 @@ public:
void after_merge_eh(unsigned r2, unsigned r1, unsigned v2, unsigned v1) {}
// this method is required by union_find
trail_stack<emonomials> & get_trail_stack() { return m_u_f_stack; }
trail_stack<emonics> & get_trail_stack() { return m_u_f_stack; }
/**
\brief push/pop scopes.
@ -150,7 +150,7 @@ public:
void pop(unsigned n);
/**
\brief create a monomial from an equality v := vs
\brief create a monic from an equality v := vs
*/
void add(lpvar v, unsigned sz, lpvar const* vs);
void add(lpvar v, svector<lpvar> const& vs) { add(v, vs.size(), vs.c_ptr()); }
@ -158,44 +158,44 @@ public:
void add(lpvar v, lpvar x, lpvar y, lpvar z) { lpvar vs[3] = { x, y, z }; add(v, 3, vs); }
/**
\brief retrieve monomial corresponding to variable v from definition v := vs
\brief retrieve monic corresponding to variable v from definition v := vs
*/
monomial const& operator[](lpvar v) const { return m_monomials[m_var2index[v]]; }
monomial & operator[](lpvar v) { return m_monomials[m_var2index[v]]; }
bool is_canonized(const monomial&) const;
bool monomials_are_canonized() const;
monic const& operator[](lpvar v) const { return m_monics[m_var2index[v]]; }
monic & operator[](lpvar v) { return m_monics[m_var2index[v]]; }
bool is_canonized(const monic&) const;
bool monics_are_canonized() const;
/**
\brief obtain the representative canonized monomial
\brief obtain the representative canonized monic
*/
monomial const& rep(monomial const& sv) const {
monic const& rep(monic const& sv) const {
unsigned j = -1;
m_cg_table.find(sv.var(), j);
return m_monomials[m_var2index[j]];
return m_monics[m_var2index[j]];
}
/**
\brief determine if m1 divides m2 over the canonization obtained from merged variables.
*/
bool canonize_divides(monomial & m1, monomial& m2) const;
bool canonize_divides(monic & m1, monic& m2) const;
/**
\brief iterator over monomials that are declared.
\brief iterator over monics that are declared.
*/
vector<monomial>::const_iterator begin() const { return m_monomials.begin(); }
vector<monomial>::const_iterator end() const { return m_monomials.end(); }
vector<monic>::const_iterator begin() const { return m_monics.begin(); }
vector<monic>::const_iterator end() const { return m_monics.end(); }
/**
\brief iterators over monomials where a variable is used
\brief iterators over monics where a variable is used
*/
class iterator {
emonomials const& m;
emonics const& m;
cell* m_cell;
bool m_touched;
public:
iterator(emonomials const& m, cell* c, bool at_end): m(m), m_cell(c), m_touched(at_end || c == nullptr) {}
monomial & operator*() { return m.m_monomials[m_cell->m_index]; }
iterator(emonics const& m, cell* c, bool at_end): m(m), m_cell(c), m_touched(at_end || c == nullptr) {}
monic & operator*() { return m.m_monics[m_cell->m_index]; }
iterator& operator++() { m_touched = true; m_cell = m_cell->m_next; return *this; }
iterator operator++(int) { iterator tmp = *this; ++*this; return tmp; }
bool operator==(iterator const& other) const { return m_cell == other.m_cell && m_touched == other.m_touched; }
@ -203,11 +203,11 @@ public:
};
class use_list {
emonomials const& m;
emonics const& m;
lpvar m_var;
cell* head() { return m.head(m_var); }
public:
use_list(emonomials const& m, lpvar v): m(m), m_var(v) {}
use_list(emonics const& m, lpvar v): m(m), m_var(v) {}
iterator begin() { return iterator(m, head(), false); }
iterator end() { return iterator(m, head(), true); }
};
@ -215,19 +215,19 @@ public:
use_list get_use_list(lpvar v) const { return use_list(*this, v); }
/**
\brief retrieve monomials m' where m is a proper factor of modulo current equalities.
\brief retrieve monics m' where m is a proper factor of modulo current equalities.
*/
class pf_iterator {
emonomials const& m_em;
monomial * m_mon; // monomial
emonics const& m_em;
monic * m_mon;
iterator m_it; // iterator over the first variable occurs list, ++ filters out elements that do not have m as a factor
iterator m_end;
void fast_forward();
public:
pf_iterator(emonomials const& m, monomial& mon, bool at_end);
pf_iterator(emonomials const& m, lpvar v, bool at_end);
monomial & operator*() {
pf_iterator(emonics const& m, monic& mon, bool at_end);
pf_iterator(emonics const& m, lpvar v, bool at_end);
monic & operator*() {
return *m_it;
}
pf_iterator& operator++() { ++m_it; fast_forward(); return *this; }
@ -237,77 +237,77 @@ public:
};
class products_of {
emonomials const& m;
monomial * mon;
emonics const& m;
monic * mon;
lpvar m_var;
public:
products_of(emonomials const& m, monomial & mon): m(m), mon(&mon), m_var(UINT_MAX) {}
products_of(emonomials const& m, lpvar v): m(m), mon(nullptr), m_var(v) {}
products_of(emonics const& m, monic & mon): m(m), mon(&mon), m_var(UINT_MAX) {}
products_of(emonics const& m, lpvar v): m(m), mon(nullptr), m_var(v) {}
pf_iterator begin() { if (mon) return pf_iterator(m, *mon, false); return pf_iterator(m, m_var, false); }
pf_iterator end() { if (mon) return pf_iterator(m, *mon, true); return pf_iterator(m, m_var, true); }
};
products_of get_products_of(monomial& m) const { inc_visited(); return products_of(*this, m); }
products_of get_products_of(monic& m) const { inc_visited(); return products_of(*this, m); }
products_of get_products_of(lpvar v) const { inc_visited(); return products_of(*this, v); }
monomial const* find_canonical(svector<lpvar> const& vars) const;
bool is_canonical_monomial(lpvar j) const {
SASSERT(is_monomial_var(j));
monic const* find_canonical(svector<lpvar> const& vars) const;
bool is_canonical_monic(lpvar j) const {
SASSERT(is_monic_var(j));
unsigned idx = m_var2index[j];
if (idx >= m_u_f.get_num_vars())
return true;
return m_u_f.find(idx) == idx;
}
/**
\brief iterator over sign equivalent monomials.
These are monomials that are equivalent modulo m_var_eqs amd modulo signs.
\brief iterator over sign equivalent monics.
These are monics that are equivalent modulo m_var_eqs amd modulo signs.
*/
class sign_equiv_monomials_it {
emonomials const& m;
class sign_equiv_monics_it {
emonics const& m;
unsigned m_index;
bool m_touched;
public:
sign_equiv_monomials_it(emonomials const& m, unsigned idx, bool at_end):
sign_equiv_monics_it(emonics const& m, unsigned idx, bool at_end):
m(m), m_index(idx), m_touched(at_end) {}
monomial const& operator*() { return m.m_monomials[m_index]; }
monic const& operator*() { return m.m_monics[m_index]; }
sign_equiv_monomials_it& operator++() {
sign_equiv_monics_it& operator++() {
m_touched = true;
if (m_index < m.m_u_f.get_num_vars())
m_index = m.m_u_f.next(m_index);
return *this;
}
sign_equiv_monomials_it operator++(int) {
sign_equiv_monomials_it tmp = *this;
sign_equiv_monics_it operator++(int) {
sign_equiv_monics_it tmp = *this;
++*this;
return tmp;
}
bool operator==(sign_equiv_monomials_it const& other) const {
bool operator==(sign_equiv_monics_it const& other) const {
return m_index == other.m_index && m_touched == other.m_touched;
}
bool operator!=(sign_equiv_monomials_it const& other) const {
bool operator!=(sign_equiv_monics_it const& other) const {
return m_index != other.m_index || m_touched != other.m_touched;
}
};
class sign_equiv_monomials {
const emonomials& em;
monomial const& m;
class sign_equiv_monics {
const emonics& em;
monic const& m;
unsigned index() const { return em.m_var2index[m.var()]; }
public:
sign_equiv_monomials(const emonomials & em, monomial const& m): em(em), m(m) {}
sign_equiv_monomials_it begin() { return sign_equiv_monomials_it(em, index(), false); }
sign_equiv_monomials_it end() { return sign_equiv_monomials_it(em, index(), true); }
sign_equiv_monics(const emonics & em, monic const& m): em(em), m(m) {}
sign_equiv_monics_it begin() { return sign_equiv_monics_it(em, index(), false); }
sign_equiv_monics_it end() { return sign_equiv_monics_it(em, index(), true); }
};
sign_equiv_monomials enum_sign_equiv_monomials(monomial const& m) const { return sign_equiv_monomials(*this, m); }
sign_equiv_monomials enum_sign_equiv_monomials(lpvar v) { return enum_sign_equiv_monomials((*this)[v]); }
sign_equiv_monics enum_sign_equiv_monics(monic const& m) const { return sign_equiv_monics(*this, m); }
sign_equiv_monics enum_sign_equiv_monics(lpvar v) { return enum_sign_equiv_monics((*this)[v]); }
/**
\brief display state of emonomials
\brief display state of emonics
*/
std::ostream& display(const core&, std::ostream& out) const;
std::ostream& display(std::ostream& out) const;
@ -323,16 +323,16 @@ public:
void unmerge_eh(signed_var r2, signed_var r1);
bool is_monomial_var(lpvar v) const { return m_var2index.get(v, UINT_MAX) != UINT_MAX; }
bool is_monic_var(lpvar v) const { return m_var2index.get(v, UINT_MAX) != UINT_MAX; }
bool elists_are_consistent(std::unordered_map<unsigned_vector, std::unordered_set<lpvar>, hash_svector> &lists) const;
}; // end of emonomials
}; // end of emonics
struct pp_emons {
const core& m_c;
const emonomials& m_em;
pp_emons(const core& c, const emonomials& e): m_c(c), m_em(e) {}
const emonics& m_em;
pp_emons(const core& c, const emonics& e): m_c(c), m_em(e) {}
inline std::ostream& display(std::ostream& out) const {
return m_em.display(m_c, out);
}

View file

@ -27,7 +27,7 @@ bool const_iterator_mon::get_factors(factor& k, factor& j, rational& sign) const
k.set(k_vars[0], factor_type::VAR);
} else {
unsigned i;
if (!m_ff->find_canonical_monomial_of_vars(k_vars, i)) {
if (!m_ff->find_canonical_monic_of_vars(k_vars, i)) {
return false;
}
k.set(i, factor_type::MON);
@ -37,7 +37,7 @@ bool const_iterator_mon::get_factors(factor& k, factor& j, rational& sign) const
j.set(j_vars[0], factor_type::VAR);
} else {
unsigned i;
if (!m_ff->find_canonical_monomial_of_vars(j_vars, i)) {
if (!m_ff->find_canonical_monic_of_vars(j_vars, i)) {
return false;
}
j.set(i, factor_type::MON);
@ -47,7 +47,7 @@ bool const_iterator_mon::get_factors(factor& k, factor& j, rational& sign) const
factorization const_iterator_mon::operator*() const {
if (m_full_factorization_returned == false) {
return create_full_factorization(m_ff->m_monomial);
return create_full_factorization(m_ff->m_monic);
}
factor j, k; rational sign;
if (!get_factors(j, k, sign))
@ -93,17 +93,17 @@ factorization const_iterator_mon::create_binary_factorization(factor j, factor k
factorization f(nullptr);
f.push_back(j);
f.push_back(k);
// Let m by *m_ff->m_monomial, the monomial we factorize
// Let m by *m_ff->m_monic, the monic we factorize
// We have canonize_sign(m)*m.vars() = m.rvars()
// Let s = canonize_sign(f). Then we have f[0]*f[1] = s*m.rvars()
// s*canonize_sign(m)*val(m).
// Therefore val(m) = sign*val((f[0])*val(f[1]), where sign = canonize_sign(f)*canonize_sign(m).
// We apply this sign to the first factor.
f[0].sign() ^= (m_ff->canonize_sign(f)^m_ff->canonize_sign(*m_ff->m_monomial));
f[0].sign() ^= (m_ff->canonize_sign(f)^m_ff->canonize_sign(*m_ff->m_monic));
return f;
}
factorization const_iterator_mon::create_full_factorization(const monomial* m) const {
factorization const_iterator_mon::create_full_factorization(const monic* m) const {
if (m != nullptr)
return factorization(m);
factorization f(nullptr);

View file

@ -20,7 +20,7 @@
--*/
#pragma once
#include "util/rational.h"
#include "math/lp/monomial.h"
#include "math/lp/monic.h"
#include "math/lp/nla_defs.h"
namespace nla {
@ -55,9 +55,9 @@ public:
class factorization {
svector<factor> m_factors;
const monomial* m_mon;
const monic* m_mon;
public:
factorization(const monomial* m): m_mon(m) {
factorization(const monic* m): m_mon(m) {
if (m != nullptr) {
for (lpvar j : m->vars())
m_factors.push_back(factor(j, factor_type::VAR));
@ -75,8 +75,8 @@ public:
void push_back(factor const& v) {
m_factors.push_back(v);
}
const monomial& mon() const { return *m_mon; }
void set_mon(const monomial* m) { m_mon = m; }
const monic& mon() const { return *m_mon; }
void set_mon(const monic* m) { m_mon = m; }
};
@ -109,19 +109,19 @@ struct const_iterator_mon {
factorization create_binary_factorization(factor j, factor k) const;
factorization create_full_factorization(const monomial*) const;
factorization create_full_factorization(const monic*) const;
};
struct factorization_factory {
const svector<lpvar>& m_vars;
const monomial* m_monomial;
const monic* m_monic;
// returns true if found
virtual bool find_canonical_monomial_of_vars(const svector<lpvar>& vars, unsigned& i) const = 0;
virtual bool canonize_sign(const monomial& m) const = 0;
virtual bool find_canonical_monic_of_vars(const svector<lpvar>& vars, unsigned& i) const = 0;
virtual bool canonize_sign(const monic& m) const = 0;
virtual bool canonize_sign(const factorization& m) const = 0;
factorization_factory(const svector<lpvar>& vars, const monomial* m) :
m_vars(vars), m_monomial(m) {
factorization_factory(const svector<lpvar>& vars, const monic* m) :
m_vars(vars), m_monic(m) {
}
svector<bool> get_mask() const {

View file

@ -21,14 +21,14 @@
#include "math/lp/nla_core.h"
namespace nla {
factorization_factory_imp::factorization_factory_imp(const monomial& rm, const core& s) :
factorization_factory_imp::factorization_factory_imp(const monic& rm, const core& s) :
factorization_factory(rm.rvars(), &s.emons()[rm.var()]),
m_core(s), m_mon(s.emons()[rm.var()]), m_rm(rm) { }
bool factorization_factory_imp::find_canonical_monomial_of_vars(const svector<lpvar>& vars, unsigned & i) const {
return m_core.find_canonical_monomial_of_vars(vars, i);
bool factorization_factory_imp::find_canonical_monic_of_vars(const svector<lpvar>& vars, unsigned & i) const {
return m_core.find_canonical_monic_of_vars(vars, i);
}
bool factorization_factory_imp::canonize_sign(const monomial& m) const {
bool factorization_factory_imp::canonize_sign(const monic& m) const {
return m_core.canonize_sign(m);
}
bool factorization_factory_imp::canonize_sign(const factorization& f) const {

View file

@ -24,12 +24,12 @@ namespace nla {
struct factorization_factory_imp: factorization_factory {
const core& m_core;
const monomial & m_mon;
const monomial& m_rm;
const monic & m_mon;
const monic& m_rm;
factorization_factory_imp(const monomial& rm, const core& s);
bool find_canonical_monomial_of_vars(const svector<lpvar>& vars, unsigned & i) const;
virtual bool canonize_sign(const monomial& m) const;
factorization_factory_imp(const monic& rm, const core& s);
bool find_canonical_monic_of_vars(const svector<lpvar>& vars, unsigned & i) const;
virtual bool canonize_sign(const monic& m) const;
virtual bool canonize_sign(const factorization& m) const;
};
}

View file

@ -48,7 +48,7 @@ bool horner::row_is_interesting(const T& row) const {
c().clear_row_var_set();
for (const auto& p : row) {
lpvar j = p.var();
if (!c().is_monomial_var(j))
if (!c().is_monic_var(j))
continue;
auto & m = c().emons()[j];
@ -133,26 +133,26 @@ void horner::horner_lemmas() {
nex * horner::nexvar(lpvar j, cross_nested& cn) const {
// todo: consider deepen the recursion
if (!c().is_monomial_var(j))
if (!c().is_monic_var(j))
return cn.mk_var(j);
const monomial& m = c().emons()[j];
const monic& m = c().emons()[j];
nex_mul * e = cn.mk_mul();
for (lpvar k : m.vars()) {
e->add_child(cn.mk_var(k));
CTRACE("nla_horner", c().is_monomial_var(k), c().print_var(k, tout) << "\n";);
CTRACE("nla_horner", c().is_monic_var(k), c().print_var(k, tout) << "\n";);
}
return e;
}
nex * horner::nexvar(const rational & coeff, lpvar j, cross_nested& cn) const {
// todo: consider deepen the recursion
if (!c().is_monomial_var(j))
if (!c().is_monic_var(j))
return cn.mk_mul(cn.mk_scalar(coeff), cn.mk_var(j));
const monomial& m = c().emons()[j];
const monic& m = c().emons()[j];
nex_mul * e = cn.mk_mul(cn.mk_scalar(coeff));
for (lpvar k : m.vars()) {
e->add_child(cn.mk_var(k));
CTRACE("nla_horner", c().is_monomial_var(k), c().print_var(k, tout) << "\n";);
CTRACE("nla_horner", c().is_monic_var(k), c().print_var(k, tout) << "\n";);
}
return e;
}

View file

@ -7,7 +7,7 @@
#include "math/lp/lar_solver.h"
#include "math/lp/lp_utils.h"
#include <utility>
#include "math/lp/monomial.h"
#include "math/lp/monic.h"
#include "math/lp/gomory.h"
namespace lp {

View file

@ -3,7 +3,7 @@
Author: Nikolaj Bjorner
*/
#include "math/lp/lar_solver.h"
#include "math/lp/monomial.h"
#include "math/lp/monic.h"
namespace nla {
template <typename T>

View file

@ -39,16 +39,16 @@ public:
};
// support the congruence
class monomial: public mon_eq {
class monic: public mon_eq {
// fields
svector<lpvar> m_rvars;
bool m_rsign;
mutable unsigned m_visited;
public:
// constructors
monomial(lpvar v, unsigned sz, lpvar const* vs, unsigned idx): monomial(v, svector<lpvar>(sz, vs), idx) {
monic(lpvar v, unsigned sz, lpvar const* vs, unsigned idx): monic(v, svector<lpvar>(sz, vs), idx) {
}
monomial(lpvar v, const svector<lpvar> &vs, unsigned idx) : mon_eq(v, vs), m_rsign(false), m_visited(0) {
monic(lpvar v, const svector<lpvar> &vs, unsigned idx) : mon_eq(v, vs), m_rsign(false), m_visited(0) {
std::sort(vars().begin(), vars().end());
}
@ -63,7 +63,7 @@ public:
}
};
inline std::ostream& operator<<(std::ostream& out, monomial const& m) {
inline std::ostream& operator<<(std::ostream& out, monic const& m) {
return out << m.var() << " := " << m.vars() << " r ( " << sign_to_rat(m.rsign()) << " * " << m.rvars() << ")";
}

View file

@ -26,7 +26,7 @@ basics::basics(core * c) : common(c) {}
// Monomials m and n vars have the same values, up to "sign"
// Generate a lemma if values of m.var() and n.var() are not the same up to sign
bool basics::basic_sign_lemma_on_two_monomials(const monomial& m, const monomial& n) {
bool basics::basic_sign_lemma_on_two_monics(const monic& m, const monic& n) {
const rational sign = sign_to_rat(m.rsign() ^ n.rsign());
if (val(m) == val(n) * sign)
return false;
@ -35,7 +35,7 @@ bool basics::basic_sign_lemma_on_two_monomials(const monomial& m, const monomial
return true;
}
void basics::generate_zero_lemmas(const monomial& m) {
void basics::generate_zero_lemmas(const monic& m) {
SASSERT(!val(m).is_zero() && c().product_value(m.vars()).is_zero());
int sign = nla::rat_sign(val(m));
unsigned_vector fixed_zeros;
@ -86,7 +86,7 @@ void basics::get_non_strict_sign(lpvar j, int& sign) const {
}
void basics::basic_sign_lemma_model_based_one_mon(const monomial& m, int product_sign) {
void basics::basic_sign_lemma_model_based_one_mon(const monic& m, int product_sign) {
if (product_sign == 0) {
TRACE("nla_solver_bl", tout << "zero product sign: " << pp_mon(_(), m)<< "\n"; );
generate_zero_lemmas(m);
@ -104,7 +104,7 @@ bool basics::basic_sign_lemma_model_based() {
unsigned start = c().random();
unsigned sz = c().m_to_refine.size();
for (unsigned i = sz; i-- > 0; ) {
monomial const& m = c().emons()[c().m_to_refine[(start + i) % sz]];
monic const& m = c().emons()[c().m_to_refine[(start + i) % sz]];
int mon_sign = nla::rat_sign(val(m));
int product_sign = c().rat_sign(m);
if (mon_sign != product_sign) {
@ -121,7 +121,7 @@ bool basics::basic_sign_lemma_on_mon(lpvar v, std::unordered_set<unsigned> & exp
if (!try_insert(v, explored)) {
return false;
}
const monomial& m_v = c().emons()[v];
const monic& m_v = c().emons()[v];
TRACE("nla_solver", tout << "m_v = " << pp_mon_with_vars(c(), m_v););
CTRACE("nla_solver", !c().emons().is_canonized(m_v),
c().emons().display(c(), tout);
@ -129,10 +129,10 @@ bool basics::basic_sign_lemma_on_mon(lpvar v, std::unordered_set<unsigned> & exp
);
SASSERT(c().emons().is_canonized(m_v));
for (auto const& m : c().emons().enum_sign_equiv_monomials(v)) {
for (auto const& m : c().emons().enum_sign_equiv_monics(v)) {
TRACE("nla_solver_details", tout << "m = " << pp_mon_with_vars(c(), m););
SASSERT(m.rvars() == m_v.rvars());
if (m_v.var() != m.var() && basic_sign_lemma_on_two_monomials(m_v, m) && done())
if (m_v.var() != m.var() && basic_sign_lemma_on_two_monics(m_v, m) && done())
return true;
}
@ -155,9 +155,9 @@ bool basics::basic_sign_lemma(bool derived) {
}
return false;
}
// the value of the i-th monomial has to be equal to the value of the k-th monomial modulo sign
// the value of the i-th monic has to be equal to the value of the k-th monic modulo sign
// but it is not the case in the model
void basics::generate_sign_lemma(const monomial& m, const monomial& n, const rational& sign) {
void basics::generate_sign_lemma(const monic& m, const monic& n, const rational& sign) {
add_empty_lemma();
TRACE("nla_solver",
tout << "m = " << pp_mon_with_vars(_(), m);
@ -172,7 +172,7 @@ void basics::generate_sign_lemma(const monomial& m, const monomial& n, const rat
}
// try to find a variable j such that val(j) = 0
// and the bounds on j contain 0 as an inner point
lpvar basics::find_best_zero(const monomial& m, unsigned_vector & fixed_zeros) const {
lpvar basics::find_best_zero(const monic& m, unsigned_vector & fixed_zeros) const {
lpvar zero_j = -1;
for (unsigned j : m.vars()){
if (val(j).is_zero()){
@ -185,13 +185,13 @@ lpvar basics::find_best_zero(const monomial& m, unsigned_vector & fixed_zeros) c
}
return zero_j;
}
void basics::add_trival_zero_lemma(lpvar zero_j, const monomial& m) {
void basics::add_trival_zero_lemma(lpvar zero_j, const monic& m) {
add_empty_lemma();
c().mk_ineq(zero_j, llc::NE);
c().mk_ineq(m.var(), llc::EQ);
TRACE("nla_solver", c().print_lemma(tout););
}
void basics::generate_strict_case_zero_lemma(const monomial& m, unsigned zero_j, int sign_of_zj) {
void basics::generate_strict_case_zero_lemma(const monic& m, unsigned zero_j, int sign_of_zj) {
TRACE("nla_solver_bl", tout << "sign_of_zj = " << sign_of_zj << "\n";);
// we know all the signs
add_empty_lemma();
@ -204,7 +204,7 @@ void basics::generate_strict_case_zero_lemma(const monomial& m, unsigned zero_j,
negate_strict_sign(m.var());
TRACE("nla_solver", c().print_lemma(tout););
}
void basics::add_fixed_zero_lemma(const monomial& m, lpvar j) {
void basics::add_fixed_zero_lemma(const monic& m, lpvar j) {
add_empty_lemma();
c().explain_fixed_var(j);
c().mk_ineq(m.var(), llc::EQ);
@ -229,11 +229,11 @@ void basics::negate_strict_sign(lpvar j) {
// here we use the fact
// xy = 0 -> x = 0 or y = 0
bool basics::basic_lemma_for_mon_zero(const monomial& rm, const factorization& f) {
bool basics::basic_lemma_for_mon_zero(const monic& rm, const factorization& f) {
NOT_IMPLEMENTED_YET();
return true;
#if 0
TRACE("nla_solver", c().trace_print_monomial_and_factorization(rm, f, tout););
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout););
add_empty_lemma();
c().explain_fixed_var(var(rm));
std::unordered_set<lpvar> processed;
@ -258,23 +258,23 @@ bool basics::basic_lemma(bool derived) {
unsigned sz = mon_inds_to_ref.size();
for (unsigned j = 0; j < sz; ++j) {
lpvar v = mon_inds_to_ref[(j + start) % mon_inds_to_ref.size()];
const monomial& r = c().emons()[v];
SASSERT (!c().check_monomial(c().emons()[v]));
const monic& r = c().emons()[v];
SASSERT (!c().check_monic(c().emons()[v]));
basic_lemma_for_mon(r, derived);
}
return false;
}
// Use basic multiplication properties to create a lemma
// for the given monomial.
// for the given monic.
// "derived" means derived from constraints - the alternative is model based
void basics::basic_lemma_for_mon(const monomial& rm, bool derived) {
void basics::basic_lemma_for_mon(const monic& rm, bool derived) {
if (derived)
basic_lemma_for_mon_derived(rm);
else
basic_lemma_for_mon_model_based(rm);
}
bool basics::basic_lemma_for_mon_derived(const monomial& rm) {
bool basics::basic_lemma_for_mon_derived(const monic& rm) {
if (c().var_is_fixed_to_zero(var(rm))) {
for (auto factorization : factorization_factory_imp(rm, c())) {
if (factorization.is_empty())
@ -300,8 +300,8 @@ bool basics::basic_lemma_for_mon_derived(const monomial& rm) {
return false;
}
// x = 0 or y = 0 -> xy = 0
bool basics::basic_lemma_for_mon_non_zero_derived(const monomial& rm, const factorization& f) {
TRACE("nla_solver", c().trace_print_monomial_and_factorization(rm, f, tout););
bool basics::basic_lemma_for_mon_non_zero_derived(const monic& rm, const factorization& f) {
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout););
if (! c().var_is_separated_from_zero(var(rm)))
return false;
int zero_j = -1;
@ -324,11 +324,11 @@ bool basics::basic_lemma_for_mon_non_zero_derived(const monomial& rm, const fact
}
// use the fact that
// |xabc| = |x| and x != 0 -> |a| = |b| = |c| = 1
bool basics::basic_lemma_for_mon_neutral_monomial_to_factor_derived(const monomial& rm, const factorization& f) {
TRACE("nla_solver", c().trace_print_monomial_and_factorization(rm, f, tout););
bool basics::basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm, const factorization& f) {
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout););
lpvar mon_var = c().emons()[rm.var()].var();
TRACE("nla_solver", c().trace_print_monomial_and_factorization(rm, f, tout); tout << "\nmon_var = " << mon_var << "\n";);
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout); tout << "\nmon_var = " << mon_var << "\n";);
const auto mv = val(mon_var);
const auto abs_mv = abs(mv);
@ -383,13 +383,13 @@ bool basics::basic_lemma_for_mon_neutral_monomial_to_factor_derived(const monomi
return true;
}
bool basics::basic_lemma_for_mon_neutral_derived(const monomial& rm, const factorization& factorization) {
bool basics::basic_lemma_for_mon_neutral_derived(const monic& rm, const factorization& factorization) {
return
basic_lemma_for_mon_neutral_monomial_to_factor_derived(rm, factorization);
basic_lemma_for_mon_neutral_monic_to_factor_derived(rm, factorization);
}
// x != 0 or y = 0 => |xy| >= |y|
void basics::proportion_lemma_model_based(const monomial& rm, const factorization& factorization) {
void basics::proportion_lemma_model_based(const monic& rm, const factorization& factorization) {
rational rmv = abs(val(rm));
if (rmv.is_zero()) {
SASSERT(c().has_zero_factor(factorization));
@ -405,7 +405,7 @@ void basics::proportion_lemma_model_based(const monomial& rm, const factorizatio
}
}
// x != 0 or y = 0 => |xy| >= |y|
bool basics::proportion_lemma_derived(const monomial& rm, const factorization& factorization) {
bool basics::proportion_lemma_derived(const monic& rm, const factorization& factorization) {
return false;
rational rmv = abs(val(rm));
if (rmv.is_zero()) {
@ -423,7 +423,7 @@ bool basics::proportion_lemma_derived(const monomial& rm, const factorization& f
return false;
}
// if there are no zero factors then |m| >= |m[factor_index]|
void basics::generate_pl_on_mon(const monomial& m, unsigned factor_index) {
void basics::generate_pl_on_mon(const monic& m, unsigned factor_index) {
add_empty_lemma();
unsigned mon_var = m.var();
rational mv = val(mon_var);
@ -446,11 +446,11 @@ void basics::generate_pl_on_mon(const monomial& m, unsigned factor_index) {
// none of the factors is zero and the product is not zero
// -> |fc[factor_index]| <= |rm|
void basics::generate_pl(const monomial& m, const factorization& fc, int factor_index) {
void basics::generate_pl(const monic& m, const factorization& fc, int factor_index) {
TRACE("nla_solver", tout << "factor_index = " << factor_index << ", m = "
<< pp_mon(c(), m);
tout << ", fc = "; c().print_factorization(fc, tout);
tout << "orig mon = "; c().print_monomial(c().emons()[m.var()], tout););
tout << "orig mon = "; c().print_monic(c().emons()[m.var()], tout););
if (fc.is_mon()) {
generate_pl_on_mon(m, factor_index);
return;
@ -492,8 +492,8 @@ bool basics::is_separated_from_zero(const factorization& f) const {
// here we use the fact xy = 0 -> x = 0 or y = 0
void basics::basic_lemma_for_mon_zero_model_based(const monomial& rm, const factorization& f) {
TRACE("nla_solver", c().trace_print_monomial_and_factorization(rm, f, tout););
void basics::basic_lemma_for_mon_zero_model_based(const monic& rm, const factorization& f) {
TRACE("nla_solver", c().trace_print_monic_and_factorization(rm, f, tout););
SASSERT(val(rm).is_zero()&& ! c().rm_check(rm));
add_empty_lemma();
if (!is_separated_from_zero(f)) {
@ -511,7 +511,7 @@ void basics::basic_lemma_for_mon_zero_model_based(const monomial& rm, const fact
TRACE("nla_solver", c().print_lemma(tout););
}
void basics::basic_lemma_for_mon_model_based(const monomial& rm) {
void basics::basic_lemma_for_mon_model_based(const monic& rm) {
TRACE("nla_solver_bl", tout << "rm = " << pp_mon(_(), rm) << "\n";);
if (val(rm).is_zero()) {
for (auto factorization : factorization_factory_imp(rm, c())) {
@ -533,8 +533,8 @@ void basics::basic_lemma_for_mon_model_based(const monomial& rm) {
// use the fact that
// |xabc| = |x| and x != 0 -> |a| = |b| = |c| = 1
bool basics::basic_lemma_for_mon_neutral_monomial_to_factor_model_based_fm(const monomial& m) {
TRACE("nla_solver_bl", c().print_monomial(m, tout););
bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based_fm(const monic& m) {
TRACE("nla_solver_bl", c().print_monic(m, tout););
lpvar mon_var = m.var();
const auto mv = val(mon_var);
@ -586,10 +586,10 @@ bool basics::basic_lemma_for_mon_neutral_monomial_to_factor_model_based_fm(const
}
// use the fact
// 1 * 1 ... * 1 * x * 1 ... * 1 = x
bool basics::basic_lemma_for_mon_neutral_from_factors_to_monomial_model_based_fm(const monomial& m) {
bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based_fm(const monic& m) {
lpvar not_one = -1;
rational sign(1);
TRACE("nla_solver_bl", tout << "m = "; c().print_monomial(m, tout););
TRACE("nla_solver_bl", tout << "m = "; c().print_monic(m, tout););
for (auto j : m.vars()){
auto v = val(j);
if (v == rational(1)) {
@ -631,11 +631,11 @@ bool basics::basic_lemma_for_mon_neutral_from_factors_to_monomial_model_based_fm
// use the fact that
// |xabc| = |x| and x != 0 -> |a| = |b| = |c| = 1
bool basics::basic_lemma_for_mon_neutral_monomial_to_factor_model_based(const monomial& rm, const factorization& f) {
TRACE("nla_solver_bl", c().trace_print_monomial_and_factorization(rm, f, tout););
bool basics::basic_lemma_for_mon_neutral_monic_to_factor_model_based(const monic& rm, const factorization& f) {
TRACE("nla_solver_bl", c().trace_print_monic_and_factorization(rm, f, tout););
lpvar mon_var = c().emons()[rm.var()].var();
TRACE("nla_solver_bl", c().trace_print_monomial_and_factorization(rm, f, tout); tout << "\nmon_var = " << mon_var << "\n";);
TRACE("nla_solver_bl", c().trace_print_monic_and_factorization(rm, f, tout); tout << "\nmon_var = " << mon_var << "\n";);
const auto mv = val(mon_var);
const auto abs_mv = abs(mv);
@ -689,19 +689,19 @@ bool basics::basic_lemma_for_mon_neutral_monomial_to_factor_model_based(const mo
return true;
}
void basics::basic_lemma_for_mon_neutral_model_based(const monomial& rm, const factorization& f) {
void basics::basic_lemma_for_mon_neutral_model_based(const monic& rm, const factorization& f) {
if (f.is_mon()) {
basic_lemma_for_mon_neutral_monomial_to_factor_model_based_fm(f.mon());
basic_lemma_for_mon_neutral_from_factors_to_monomial_model_based_fm(f.mon());
basic_lemma_for_mon_neutral_monic_to_factor_model_based_fm(f.mon());
basic_lemma_for_mon_neutral_from_factors_to_monic_model_based_fm(f.mon());
}
else {
basic_lemma_for_mon_neutral_monomial_to_factor_model_based(rm, f);
basic_lemma_for_mon_neutral_from_factors_to_monomial_model_based(rm, f);
basic_lemma_for_mon_neutral_monic_to_factor_model_based(rm, f);
basic_lemma_for_mon_neutral_from_factors_to_monic_model_based(rm, f);
}
}
// use the fact
// 1 * 1 ... * 1 * x * 1 ... * 1 = x
bool basics::basic_lemma_for_mon_neutral_from_factors_to_monomial_model_based(const monomial& m, const factorization& f) {
bool basics::basic_lemma_for_mon_neutral_from_factors_to_monic_model_based(const monic& m, const factorization& f) {
rational sign = sign_to_rat(m.rsign());
SASSERT(m.rsign() == canonize_sign(f));
TRACE("nla_solver_bl", tout << pp_mon_with_vars(_(), m) <<"\nf = "; c().print_factorization(f, tout); tout << "sign = " << sign << '\n'; );
@ -784,8 +784,8 @@ void basics::basic_lemma_for_mon_non_zero_model_based_mf(const factorization& f)
}
// x = 0 or y = 0 -> xy = 0
void basics::basic_lemma_for_mon_non_zero_model_based(const monomial& rm, const factorization& f) {
TRACE("nla_solver_bl", c().trace_print_monomial_and_factorization(rm, f, tout););
void basics::basic_lemma_for_mon_non_zero_model_based(const monic& rm, const factorization& f) {
TRACE("nla_solver_bl", c().trace_print_monic_and_factorization(rm, f, tout););
if (f.is_mon())
basic_lemma_for_mon_non_zero_model_based_mf(f);
else

View file

@ -18,7 +18,7 @@
--*/
#pragma once
#include "math/lp/monomial.h"
#include "math/lp/monic.h"
#include "math/lp/factorization.h"
#include "math/lp/nla_common.h"
@ -27,9 +27,9 @@ namespace nla {
class core;
struct basics: common {
basics(core *core);
bool basic_sign_lemma_on_two_monomials(const monomial& m, const monomial& n);
bool basic_sign_lemma_on_two_monics(const monic& m, const monic& n);
void basic_sign_lemma_model_based_one_mon(const monomial& m, int product_sign);
void basic_sign_lemma_model_based_one_mon(const monic& m, int product_sign);
bool basic_sign_lemma_model_based();
bool basic_sign_lemma_on_mon(unsigned i, std::unordered_set<unsigned> & explore);
@ -39,69 +39,69 @@ struct basics: common {
-ab = a(-b)
*/
bool basic_sign_lemma(bool derived);
bool basic_lemma_for_mon_zero(const monomial& rm, const factorization& f);
bool basic_lemma_for_mon_zero(const monic& rm, const factorization& f);
void basic_lemma_for_mon_zero_model_based(const monomial& rm, const factorization& f);
void basic_lemma_for_mon_zero_model_based(const monic& rm, const factorization& f);
void basic_lemma_for_mon_non_zero_model_based(const monomial& rm, const factorization& f);
void basic_lemma_for_mon_non_zero_model_based(const monic& rm, const factorization& f);
// x = 0 or y = 0 -> xy = 0
void basic_lemma_for_mon_non_zero_model_based_rm(const monomial& rm, const factorization& f);
void basic_lemma_for_mon_non_zero_model_based_rm(const monic& rm, const factorization& f);
void basic_lemma_for_mon_non_zero_model_based_mf(const factorization& f);
// x = 0 or y = 0 -> xy = 0
bool basic_lemma_for_mon_non_zero_derived(const monomial& rm, const factorization& f);
bool basic_lemma_for_mon_non_zero_derived(const monic& rm, const factorization& f);
// use the fact that
// |xabc| = |x| and x != 0 -> |a| = |b| = |c| = 1
bool basic_lemma_for_mon_neutral_monomial_to_factor_model_based(const monomial& rm, const factorization& f);
bool basic_lemma_for_mon_neutral_monic_to_factor_model_based(const monic& rm, const factorization& f);
// use the fact that
// |xabc| = |x| and x != 0 -> |a| = |b| = |c| = 1
bool basic_lemma_for_mon_neutral_monomial_to_factor_model_based_fm(const monomial& m);
bool basic_lemma_for_mon_neutral_monomial_to_factor_derived(const monomial& rm, const factorization& f);
bool basic_lemma_for_mon_neutral_monic_to_factor_model_based_fm(const monic& m);
bool basic_lemma_for_mon_neutral_monic_to_factor_derived(const monic& rm, const factorization& f);
// use the fact
// 1 * 1 ... * 1 * x * 1 ... * 1 = x
bool basic_lemma_for_mon_neutral_from_factors_to_monomial_model_based(const monomial& rm, const factorization& f);
bool basic_lemma_for_mon_neutral_from_factors_to_monic_model_based(const monic& rm, const factorization& f);
// use the fact
// 1 * 1 ... * 1 * x * 1 ... * 1 = x
bool basic_lemma_for_mon_neutral_from_factors_to_monomial_model_based_fm(const monomial& m);
bool basic_lemma_for_mon_neutral_from_factors_to_monic_model_based_fm(const monic& m);
// use the fact
// 1 * 1 ... * 1 * x * 1 ... * 1 = x
bool basic_lemma_for_mon_neutral_from_factors_to_monomial_derived(const monomial& rm, const factorization& f);
void basic_lemma_for_mon_neutral_model_based(const monomial& rm, const factorization& f);
bool basic_lemma_for_mon_neutral_from_factors_to_monic_derived(const monic& rm, const factorization& f);
void basic_lemma_for_mon_neutral_model_based(const monic& rm, const factorization& f);
bool basic_lemma_for_mon_neutral_derived(const monomial& rm, const factorization& factorization);
bool basic_lemma_for_mon_neutral_derived(const monic& rm, const factorization& factorization);
void basic_lemma_for_mon_model_based(const monomial& rm);
void basic_lemma_for_mon_model_based(const monic& rm);
bool basic_lemma_for_mon_derived(const monomial& rm);
bool basic_lemma_for_mon_derived(const monic& rm);
// Use basic multiplication properties to create a lemma
// for the given monomial.
// for the given monic.
// "derived" means derived from constraints - the alternative is model based
void basic_lemma_for_mon(const monomial& rm, bool derived);
void basic_lemma_for_mon(const monic& rm, bool derived);
// use basic multiplication properties to create a lemma
bool basic_lemma(bool derived);
void generate_sign_lemma(const monomial& m, const monomial& n, const rational& sign);
void generate_zero_lemmas(const monomial& m);
lpvar find_best_zero(const monomial& m, unsigned_vector & fixed_zeros) const;
void generate_sign_lemma(const monic& m, const monic& n, const rational& sign);
void generate_zero_lemmas(const monic& m);
lpvar find_best_zero(const monic& m, unsigned_vector & fixed_zeros) const;
bool try_get_non_strict_sign_from_bounds(lpvar j, int& sign) const;
void get_non_strict_sign(lpvar j, int& sign) const;
void add_trival_zero_lemma(lpvar zero_j, const monomial& m);
void generate_strict_case_zero_lemma(const monomial& m, unsigned zero_j, int sign_of_zj);
void add_trival_zero_lemma(lpvar zero_j, const monic& m);
void generate_strict_case_zero_lemma(const monic& m, unsigned zero_j, int sign_of_zj);
void add_fixed_zero_lemma(const monomial& m, lpvar j);
void add_fixed_zero_lemma(const monic& m, lpvar j);
void negate_strict_sign(lpvar j);
// x != 0 or y = 0 => |xy| >= |y|
void proportion_lemma_model_based(const monomial& rm, const factorization& factorization);
void proportion_lemma_model_based(const monic& rm, const factorization& factorization);
// x != 0 or y = 0 => |xy| >= |y|
bool proportion_lemma_derived(const monomial& rm, const factorization& factorization);
bool proportion_lemma_derived(const monic& rm, const factorization& factorization);
// if there are no zero factors then |m| >= |m[factor_index]|
void generate_pl_on_mon(const monomial& m, unsigned factor_index);
void generate_pl_on_mon(const monic& m, unsigned factor_index);
// none of the factors is zero and the product is not zero
// -> |fc[factor_index]| <= |rm|
void generate_pl(const monomial& rm, const factorization& fc, int factor_index);
void generate_pl(const monic& rm, const factorization& fc, int factor_index);
bool is_separated_from_zero(const factorization&) const;
};
}

View file

@ -26,25 +26,25 @@ bool common::done() const { return c().done(); }
template <typename T> void common::explain(const T& t) {
c().explain(t, c().current_expl());
}
template void common::explain<monomial>(const monomial& t);
template void common::explain<monic>(const monic& t);
template void common::explain<factor>(const factor& t);
template void common::explain<factorization>(const factorization& t);
void common::explain(lpvar j) { c().explain(j, c().current_expl()); }
template <typename T> rational common::val(T const& t) const { return c().val(t); }
template rational common::val<monomial>(monomial const& t) const;
template rational common::val<monic>(monic const& t) const;
template rational common::val<factor>(factor const& t) const;
rational common::val(lpvar t) const { return c().val(t); }
template <typename T> lpvar common::var(T const& t) const { return c().var(t); }
template lpvar common::var<factor>(factor const& t) const;
template lpvar common::var<monomial>(monomial const& t) const;
template lpvar common::var<monic>(monic const& t) const;
void common::add_empty_lemma() { c().add_empty_lemma(); }
template <typename T> bool common::canonize_sign(const T& t) const {
return c().canonize_sign(t);
}
template bool common::canonize_sign<monomial>(const monomial&) const;
template bool common::canonize_sign<monic>(const monic&) const;
template bool common::canonize_sign<factor>(const factor&) const;
template bool common::canonize_sign<lpvar>(const lpvar&) const;
template bool common::canonize_sign<factorization>(const factorization&) const;
@ -102,8 +102,8 @@ std::ostream& common::print_product(const T & m, std::ostream& out) const {
template
std::ostream& common::print_product<unsigned_vector>(const unsigned_vector & m, std::ostream& out) const;
std::ostream& common::print_monomial(const monomial & m, std::ostream& out) const {
return c().print_monomial(m, out);
std::ostream& common::print_monic(const monic & m, std::ostream& out) const {
return c().print_monic(m, out);
}
std::ostream& common::print_factor(const factor & f, std::ostream& out) const {
@ -114,8 +114,8 @@ std::ostream& common::print_var(lpvar j, std::ostream& out) const {
return c().print_var(j, out);
}
bool common::check_monomial(const monomial& m) const {
return c().check_monomial(m);
bool common::check_monic(const monic& m) const {
return c().check_monic(m);
}
unsigned common::random() {

View file

@ -21,7 +21,7 @@
#include "util/rational.h"
#include "math/lp/nla_defs.h"
#include "math/lp/lar_term.h"
#include "math/lp/monomial.h"
#include "math/lp/monic.h"
#include "math/lp/emonomials.h"
#include "math/lp/factorization.h"
namespace nla {
@ -51,7 +51,7 @@ struct common {
template <typename T> rational val(T const& t) const;
rational val(lpvar) const;
rational rval(const monomial&) const;
rational rval(const monic&) const;
template <typename T> lpvar var(T const& t) const;
bool done() const;
template <typename T> void explain(const T&);
@ -87,10 +87,10 @@ struct common {
std::ostream& print_factor(const factor &, std::ostream& out) const;
std::ostream& print_var(lpvar, std::ostream& out) const;
std::ostream& print_monomial(const monomial & m, std::ostream& out) const;
std::ostream& print_rooted_monomial(const monomial &, std::ostream& out) const;
std::ostream& print_rooted_monomial_with_vars(const monomial&, std::ostream& out) const;
bool check_monomial(const monomial&) const;
std::ostream& print_monic(const monic & m, std::ostream& out) const;
std::ostream& print_rooted_monic(const monic &, std::ostream& out) const;
std::ostream& print_rooted_monic_with_vars(const monic&, std::ostream& out) const;
bool check_monic(const monic&) const;
unsigned random();
};
}

View file

@ -104,7 +104,7 @@ bool core::canonize_sign(lpvar j) const {
return m_evars.find(j).sign();
}
bool core::canonize_sign_is_correct(const monomial& m) const {
bool core::canonize_sign_is_correct(const monic& m) const {
bool r = false;
for (lpvar j : m.vars()) {
r ^= canonize_sign(j);
@ -112,7 +112,7 @@ bool core::canonize_sign_is_correct(const monomial& m) const {
return r == m.rsign();
}
bool core::canonize_sign(const monomial& m) const {
bool core::canonize_sign(const monic& m) const {
SASSERT(canonize_sign_is_correct(m));
return m.rsign();
}
@ -125,7 +125,7 @@ bool core::canonize_sign(const factorization& f) const {
return r;
}
void core::add_monomial(lpvar v, unsigned sz, lpvar const* vs) {
void core::add_monic(lpvar v, unsigned sz, lpvar const* vs) {
m_add_buffer.resize(sz);
for (unsigned i = 0; i < sz; i++) {
lpvar j = vs[i];
@ -157,13 +157,13 @@ rational core::product_value(const unsigned_vector & m) const {
return r;
}
// return true iff the monomial value is equal to the product of the values of the factors
bool core::check_monomial(const monomial& m) const {
// return true iff the monic value is equal to the product of the values of the factors
bool core::check_monic(const monic& m) const {
SASSERT(m_lar_solver.get_column_value(m.var()).is_int());
return product_value(m.vars()) == m_lar_solver.get_column_value_rational(m.var());
}
void core::explain(const monomial& m, lp::explanation& exp) const {
void core::explain(const monic& m, lp::explanation& exp) const {
for (lpvar j : m.vars())
explain(j, exp);
}
@ -231,7 +231,7 @@ std::ostream & core::print_factor_with_vars(const factor& f, std::ostream& out)
return out;
}
std::ostream& core::print_monomial(const monomial& m, std::ostream& out) const {
std::ostream& core::print_monic(const monic& m, std::ostream& out) const {
if (lp_settings().m_print_external_var_name)
out << "([" << m.var() << "] = " << m_lar_solver.get_variable_name(m.var()) << " = " << val(m.var()) << " = ";
else
@ -250,8 +250,8 @@ std::ostream& core::print_bfc(const factorization& m, std::ostream& out) const {
return out;
}
std::ostream& core::print_monomial_with_vars(lpvar v, std::ostream& out) const {
return print_monomial_with_vars(m_emons[v], out);
std::ostream& core::print_monic_with_vars(lpvar v, std::ostream& out) const {
return print_monic_with_vars(m_emons[v], out);
}
template <typename T>
std::ostream& core::print_product_with_vars(const T& m, std::ostream& out) const {
@ -262,7 +262,7 @@ std::ostream& core::print_product_with_vars(const T& m, std::ostream& out) const
return out;
}
std::ostream& core::print_monomial_with_vars(const monomial& m, std::ostream& out) const {
std::ostream& core::print_monic_with_vars(const monic& m, std::ostream& out) const {
out << "["; print_var(m.var(), out) << "]\n";
out << "vars:"; print_product_with_vars(m.vars(), out) << "\n";
if (m.vars() == m.rvars())
@ -505,8 +505,8 @@ void core:: mk_ineq(lpvar j, llc cmp) {
mk_ineq(j, cmp, rational::zero());
}
// the monomials should be equal by modulo sign but this is not so in the model
void core:: fill_explanation_and_lemma_sign(const monomial& a, const monomial & b, rational const& sign) {
// the monics should be equal by modulo sign but this is not so in the model
void core:: fill_explanation_and_lemma_sign(const monic& a, const monic & b, rational const& sign) {
SASSERT(sign == 1 || sign == -1);
explain(a, current_expl());
explain(b, current_expl());
@ -523,7 +523,7 @@ void core:: fill_explanation_and_lemma_sign(const monomial& a, const monomial &
// Replaces each variable index by the root in the tree and flips the sign if the var comes with a minus.
// Also sorts the result.
//
svector<lpvar> core::reduce_monomial_to_rooted(const svector<lpvar> & vars, rational & sign) const {
svector<lpvar> core::reduce_monic_to_rooted(const svector<lpvar> & vars, rational & sign) const {
svector<lpvar> ret;
bool s = false;
for (lpvar v : vars) {
@ -545,10 +545,10 @@ svector<lpvar> core::reduce_monomial_to_rooted(const svector<lpvar> & vars, rati
// m_v = coeff * w1 * ... * wn, where w1, .., wn are canonical
// representatives, which are the roots of the equivalence tree, under current equations.
//
monomial_coeff core::canonize_monomial(monomial const& m) const {
monic_coeff core::canonize_monic(monic const& m) const {
rational sign = rational(1);
svector<lpvar> vars = reduce_monomial_to_rooted(m.vars(), sign);
return monomial_coeff(vars, sign);
svector<lpvar> vars = reduce_monic_to_rooted(m.vars(), sign);
return monic_coeff(vars, sign);
}
lemma& core::current_lemma() { return m_lemma_vec->back(); }
@ -594,7 +594,7 @@ bool core::zero_is_an_inner_point_of_bounds(lpvar j) const {
return true;
}
int core::rat_sign(const monomial& m) const {
int core::rat_sign(const monic& m) const {
int sign = 1;
for (lpvar j : m.vars()) {
auto v = val(j);
@ -611,8 +611,8 @@ int core::rat_sign(const monomial& m) const {
return sign;
}
// Returns true if the monomial sign is incorrect
bool core::sign_contradiction(const monomial& m) const {
// Returns true if the monic sign is incorrect
bool core::sign_contradiction(const monic& m) const {
return nla::rat_sign(val(m)) != rat_sign(m);
}
@ -654,8 +654,8 @@ std::ostream & core::print_ineq(const ineq & in, std::ostream & out) const {
}
std::ostream & core::print_var(lpvar j, std::ostream & out) const {
if (m_emons.is_monomial_var(j)) {
print_monomial(m_emons[j], out);
if (m_emons.is_monic_var(j)) {
print_monic(m_emons[j], out);
}
m_lar_solver.print_column_info(j, out);
@ -664,9 +664,9 @@ std::ostream & core::print_var(lpvar j, std::ostream & out) const {
return out;
}
std::ostream & core::print_monomials(std::ostream & out) const {
std::ostream & core::print_monics(std::ostream & out) const {
for (auto &m : m_emons) {
print_monomial_with_vars(m, out);
print_monic_with_vars(m, out);
}
return out;
}
@ -707,13 +707,13 @@ std::ostream & core::print_factorization(const factorization& f, std::ostream& o
return out;
}
bool core::find_canonical_monomial_of_vars(const svector<lpvar>& vars, lpvar & i) const {
monomial const* sv = m_emons.find_canonical(vars);
bool core::find_canonical_monic_of_vars(const svector<lpvar>& vars, lpvar & i) const {
monic const* sv = m_emons.find_canonical(vars);
return sv && (i = sv->var(), true);
}
bool core::is_canonical_monomial(lpvar j) const {
return m_emons.is_canonical_monomial(j);
bool core::is_canonical_monic(lpvar j) const {
return m_emons.is_canonical_monic(j);
}
@ -735,7 +735,7 @@ void core::explain_separation_from_zero(lpvar j) {
explain_existing_upper_bound(j);
}
void core::trace_print_monomial_and_factorization(const monomial& rm, const factorization& f, std::ostream& out) const {
void core::trace_print_monic_and_factorization(const monic& rm, const factorization& f, std::ostream& out) const {
out << "rooted vars: ";
print_product(rm.rvars(), out);
out << "\n";
@ -926,14 +926,14 @@ void core::trace_print_rms(const T& p, std::ostream& out) {
out << "}";
}
void core::print_monomial_stats(const monomial& m, std::ostream& out) {
void core::print_monic_stats(const monic& m, std::ostream& out) {
if (m.size() == 2) return;
monomial_coeff mc = canonize_monomial(m);
monic_coeff mc = canonize_monic(m);
for(unsigned i = 0; i < mc.vars().size(); i++){
if (abs(val(mc.vars()[i])) == rational(1)) {
auto vv = mc.vars();
vv.erase(vv.begin()+i);
monomial const* sv = m_emons.find_canonical(vv);
monic const* sv = m_emons.find_canonical(vv);
if (!sv) {
out << "nf length" << vv.size() << "\n"; ;
}
@ -959,10 +959,10 @@ void core::init_to_refine() {
TRACE("nla_solver_details", tout << "emons:" << pp_emons(*this, m_emons););
m_to_refine.clear();
m_to_refine.resize(m_lar_solver.number_of_vars());
unsigned r = random(), sz = m_emons.number_of_monomials();
unsigned r = random(), sz = m_emons.number_of_monics();
for (unsigned k = 0; k < sz; k++) {
auto const & m = *(m_emons.begin() + (k + r)% sz);
if (!check_monomial(m))
if (!check_monic(m))
m_to_refine.insert(m.var());
}
@ -975,7 +975,7 @@ std::unordered_set<lpvar> core::collect_vars(const lemma& l) const {
std::unordered_set<lpvar> vars;
auto insert_j = [&](lpvar j) {
vars.insert(j);
if (m_emons.is_monomial_var(j)) {
if (m_emons.is_monic_var(j)) {
for (lpvar k : m_emons[j].vars())
vars.insert(k);
}
@ -996,7 +996,7 @@ std::unordered_set<lpvar> core::collect_vars(const lemma& l) const {
}
// divides bc by c, so bc = b*c
bool core::divide(const monomial& bc, const factor& c, factor & b) const {
bool core::divide(const monic& bc, const factor& c, factor & b) const {
svector<lpvar> c_rvars = sorted_rvars(c);
TRACE("nla_solver_div", tout << "c_rvars = "; print_product(c_rvars, tout); tout << "\nbc_rvars = "; print_product(bc.rvars(), tout););
if (!lp::is_proper_factor(c_rvars, bc.rvars()))
@ -1008,7 +1008,7 @@ bool core::divide(const monomial& bc, const factor& c, factor & b) const {
if (b_rvars.size() == 1) {
b = factor(b_rvars[0], factor_type::VAR);
} else {
monomial const* sv = m_emons.find_canonical(b_rvars);
monic const* sv = m_emons.find_canonical(b_rvars);
if (sv == nullptr) {
TRACE("nla_solver_div", tout << "not in rooted";);
return false;
@ -1064,10 +1064,10 @@ void core::print_specific_lemma(const lemma& l, std::ostream& out) const {
}
void core::trace_print_ol(const monomial& ac,
void core::trace_print_ol(const monic& ac,
const factor& a,
const factor& c,
const monomial& bc,
const monic& bc,
const factor& b,
std::ostream& out) {
out << "ac = " << pp_mon(*this, ac) << "\n";
@ -1086,7 +1086,7 @@ void core::maybe_add_a_factor(lpvar i,
std::unordered_set<unsigned>& found_rm,
vector<factor> & r) const {
SASSERT(abs(val(i)) == abs(val(c)));
if (!m_emons.is_monomial_var(i)) {
if (!m_emons.is_monic_var(i)) {
i = m_evars.find(i).var();
if (try_insert(i, found_vars)) {
r.push_back(factor(i, factor_type::VAR));
@ -1100,7 +1100,7 @@ void core::maybe_add_a_factor(lpvar i,
}
// Returns rooted monomials by arity
// Returns rooted monics by arity
std::unordered_map<unsigned, unsigned_vector> core::get_rm_by_arity() {
std::unordered_map<unsigned, unsigned_vector> m;
for (auto const& mon : m_emons) {
@ -1116,8 +1116,8 @@ std::unordered_map<unsigned, unsigned_vector> core::get_rm_by_arity() {
bool core::rm_check(const monomial& rm) const {
return check_monomial(m_emons[rm.var()]);
bool core::rm_check(const monic& rm) const {
return check_monic(m_emons[rm.var()]);
}
@ -1174,7 +1174,7 @@ void core::add_abs_bound(lpvar v, llc cmp, rational const& bound) {
*/
bool core::find_bfc_to_refine_on_monomial(const monomial& m, factorization & bf) {
bool core::find_bfc_to_refine_on_monic(const monic& m, factorization & bf) {
for (auto f : factorization_factory_imp(m, *this)) {
if (f.size() == 2) {
auto a = f[0];
@ -1192,14 +1192,14 @@ bool core::find_bfc_to_refine_on_monomial(const monomial& m, factorization & bf)
return false;
}
// finds a monomial to refine with its binary factorization
bool core::find_bfc_to_refine(const monomial* & m, factorization & bf){
// finds a monic to refine with its binary factorization
bool core::find_bfc_to_refine(const monic* & m, factorization & bf){
m = nullptr;
unsigned r = random(), sz = m_to_refine.size();
for (unsigned k = 0; k < sz; k++) {
lpvar i = m_to_refine[(k + r) % sz];
m = &m_emons[i];
SASSERT (!check_monomial(*m));
SASSERT (!check_monic(*m));
if (m->size() == 2) {
bf.set_mon(m);
bf.push_back(factor(m->vars()[0], factor_type::VAR));
@ -1207,7 +1207,7 @@ bool core::find_bfc_to_refine(const monomial* & m, factorization & bf){
return true;
}
if (find_bfc_to_refine_on_monomial(*m, bf)) {
if (find_bfc_to_refine_on_monic(*m, bf)) {
TRACE("nla_solver",
tout << "bf = "; print_factorization(bf, tout);
tout << "\nval(*m) = " << val(*m) << ", should be = (val(bf[0])=" << val(bf[0]) << ")*(val(bf[1]) = " << val(bf[1]) << ") = " << val(bf[0])*val(bf[1]) << "\n";);
@ -1292,10 +1292,10 @@ bool core::elist_is_consistent(const std::unordered_set<lpvar> & list) const {
bool p;
for (lpvar j : list) {
if (first) {
p = check_monomial(m_emons[j]);
p = check_monic(m_emons[j]);
first = false;
} else
if (check_monomial(m_emons[j]) != p)
if (check_monic(m_emons[j]) != p)
return false;
}
return true;
@ -1334,8 +1334,8 @@ lbool core::check(vector<lemma>& l_vec) {
ret = inner_check(false);
TRACE("nla_solver", tout << "ret = " << ret << ", lemmas count = " << m_lemma_vec->size() << "\n";);
IF_VERBOSE(2, if(ret == l_undef) {verbose_stream() << "Monomials\n"; print_monomials(verbose_stream());});
CTRACE("nla_solver", ret == l_undef, tout << "Monomials\n"; print_monomials(tout););
IF_VERBOSE(2, if(ret == l_undef) {verbose_stream() << "Monomials\n"; print_monics(verbose_stream());});
CTRACE("nla_solver", ret == l_undef, tout << "Monomials\n"; print_monics(tout););
return ret;
}
@ -1383,7 +1383,7 @@ lbool core::test_check(
// nla_expr<rational> r(expr_type::SUM);
// for (const auto & p : coeffs) {
// lpvar j = p.second;
// if (is_monomial_var(j))
// if (is_monic_var(j))
// r.add_child(mk_expr(p.first, m_emons[j].vars()));
// else
// r.add_child(mk_expr(p.first, j));
@ -1408,8 +1408,8 @@ std::ostream& core::print_terms(std::ostream& out) const {
}
std::string core::var_str(lpvar j) const {
return is_monomial_var(j)?
(product_indices_str(m_emons[j].vars()) + (check_monomial(m_emons[j])? "": "_")) : (std::string("v") + lp::T_to_string(j));
return is_monic_var(j)?
(product_indices_str(m_emons[j].vars()) + (check_monic(m_emons[j])? "": "_")) : (std::string("v") + lp::T_to_string(j));
}
std::ostream& core::print_term( const lp::lar_term& t, std::ostream& out) const {

View file

@ -79,7 +79,7 @@ public:
class core {
public:
var_eqs<emonomials> m_evars;
var_eqs<emonics> m_evars;
lp::lar_solver& m_lar_solver;
vector<lemma> * m_lemma_vec;
lp::int_set m_to_refine;
@ -91,7 +91,7 @@ public:
nla_settings m_nla_settings;
nla_grobner m_grobner;
private:
emonomials m_emons;
emonics m_emons;
svector<lpvar> m_add_buffer;
mutable lp::int_set m_row_var_set;
public:
@ -113,8 +113,8 @@ public:
}
reslimit & reslim() { return m_reslim; }
emonomials& emons() { return m_emons; }
const emonomials& emons() const { return m_emons; }
emonics& emons() { return m_emons; }
const emonics& emons() const { return m_emons; }
// constructor
core(lp::lar_solver& s, reslimit &);
@ -125,16 +125,16 @@ public:
lp::lar_term subs_terms_to_columns(const lp::lar_term& t) const;
bool ineq_holds(const ineq& n) const;
bool lemma_holds(const lemma& l) const;
bool is_monomial_var(lpvar j) const { return m_emons.is_monomial_var(j); }
bool is_monic_var(lpvar j) const { return m_emons.is_monic_var(j); }
rational val(lpvar j) const { return m_lar_solver.get_column_value_rational(j); }
rational val(const monomial& m) const { return m_lar_solver.get_column_value_rational(m.var()); }
rational val(const monic& m) const { return m_lar_solver.get_column_value_rational(m.var()); }
bool canonize_sign_is_correct(const monomial& m) const;
bool canonize_sign_is_correct(const monic& m) const;
lpvar var(monomial const& sv) const { return sv.var(); }
lpvar var(monic const& sv) const { return sv.var(); }
rational val_rooted(const monomial& m) const { return m.rsign()*val(m.var()); }
rational val_rooted(const monic& m) const { return m.rsign()*val(m.var()); }
rational val(const factor& f) const { return f.rat_sign() * (f.is_var()? val(f.var()) : val(m_emons[f.var()])); }
@ -161,24 +161,24 @@ public:
// the value of the rooted monomias is equal to the value of the m.var() variable multiplied
// by the canonize_sign
bool canonize_sign(const monomial& m) const;
bool canonize_sign(const monic& m) const;
void deregister_monomial_from_monomialomials (const monomial & m, unsigned i);
void deregister_monic_from_monicomials (const monic & m, unsigned i);
void deregister_monomial_from_tables(const monomial & m, unsigned i);
void deregister_monic_from_tables(const monic & m, unsigned i);
void add_monomial(lpvar v, unsigned sz, lpvar const* vs);
void add_monic(lpvar v, unsigned sz, lpvar const* vs);
void push();
void pop(unsigned n);
rational mon_value_by_vars(unsigned i) const;
rational product_value(const unsigned_vector & m) const;
// return true iff the monomial value is equal to the product of the values of the factors
bool check_monomial(const monomial& m) const;
// return true iff the monic value is equal to the product of the values of the factors
bool check_monic(const monic& m) const;
void explain(const monomial& m, lp::explanation& exp) const;
void explain(const monic& m, lp::explanation& exp) const;
void explain(const factor& f, lp::explanation& exp) const;
void explain(lpvar j, lp::explanation& exp) const;
void explain_existing_lower_bound(lpvar j);
@ -189,7 +189,7 @@ public:
std::ostream & print_ineq(const ineq & in, std::ostream & out) const;
std::ostream & print_var(lpvar j, std::ostream & out) const;
std::ostream & print_monomials(std::ostream & out) const;
std::ostream & print_monics(std::ostream & out) const;
std::ostream & print_ineqs(const lemma& l, std::ostream & out) const;
std::ostream & print_factorization(const factorization& f, std::ostream& out) const;
template <typename T>
@ -200,27 +200,27 @@ public:
std::ostream & print_factor(const factor& f, std::ostream& out) const;
std::ostream & print_factor_with_vars(const factor& f, std::ostream& out) const;
std::ostream& print_monomial(const monomial& m, std::ostream& out) const;
std::ostream& print_monic(const monic& m, std::ostream& out) const;
std::ostream& print_bfc(const factorization& m, std::ostream& out) const;
std::ostream& print_monomial_with_vars(unsigned i, std::ostream& out) const;
std::ostream& print_monic_with_vars(unsigned i, std::ostream& out) const;
template <typename T>
std::ostream& print_product_with_vars(const T& m, std::ostream& out) const;
std::ostream& print_monomial_with_vars(const monomial& m, std::ostream& out) const;
std::ostream& print_monic_with_vars(const monic& m, std::ostream& out) const;
std::ostream& print_explanation(const lp::explanation& exp, std::ostream& out) const;
template <typename T>
void trace_print_rms(const T& p, std::ostream& out);
void trace_print_monomial_and_factorization(const monomial& rm, const factorization& f, std::ostream& out) const;
void print_monomial_stats(const monomial& m, std::ostream& out);
void trace_print_monic_and_factorization(const monic& rm, const factorization& f, std::ostream& out) const;
void print_monic_stats(const monic& m, std::ostream& out);
void print_stats(std::ostream& out);
std::ostream& print_lemma(std::ostream& out) const;
void print_specific_lemma(const lemma& l, std::ostream& out) const;
void trace_print_ol(const monomial& ac,
void trace_print_ol(const monic& ac,
const factor& a,
const factor& c,
const monomial& bc,
const monic& bc,
const factor& b,
std::ostream& out);
@ -251,11 +251,11 @@ public:
llc apply_minus(llc cmp);
void fill_explanation_and_lemma_sign(const monomial& a, const monomial & b, rational const& sign);
void fill_explanation_and_lemma_sign(const monic& a, const monic & b, rational const& sign);
svector<lpvar> reduce_monomial_to_rooted(const svector<lpvar> & vars, rational & sign) const;
svector<lpvar> reduce_monic_to_rooted(const svector<lpvar> & vars, rational & sign) const;
monomial_coeff canonize_monomial(monomial const& m) const;
monic_coeff canonize_monic(monic const& m) const;
lemma& current_lemma();
const lemma& current_lemma() const;
@ -274,18 +274,18 @@ public:
bool zero_is_an_inner_point_of_bounds(lpvar j) const;
int rat_sign(const monomial& m) const;
int rat_sign(const monic& m) const;
inline int rat_sign(lpvar j) const { return nla::rat_sign(val(j)); }
bool sign_contradiction(const monomial& m) const;
bool sign_contradiction(const monic& m) const;
bool var_is_fixed_to_zero(lpvar j) const;
bool var_is_fixed_to_val(lpvar j, const rational& v) const;
bool var_is_fixed(lpvar j) const;
bool find_canonical_monomial_of_vars(const svector<lpvar>& vars, lpvar & i) const;
bool is_canonical_monomial(lpvar) const;
bool find_canonical_monic_of_vars(const svector<lpvar>& vars, lpvar & i) const;
bool is_canonical_monic(lpvar) const;
bool elists_are_consistent(bool check_in_model) const;
bool elist_is_consistent(const std::unordered_set<lpvar>&) const;
bool var_has_positive_lower_bound(lpvar j) const;
@ -337,9 +337,9 @@ public:
template <typename T>
bool vars_are_roots(const T& v) const;
void register_monomial_in_tables(unsigned i_mon);
void register_monic_in_tables(unsigned i_mon);
void register_monomials_in_tables();
void register_monics_in_tables();
void clear();
@ -347,7 +347,7 @@ public:
void init_to_refine();
bool divide(const monomial& bc, const factor& c, factor & b) const;
bool divide(const monic& bc, const factor& c, factor & b) const;
void negate_factor_equality(const factor& c, const factor& d);
@ -355,15 +355,15 @@ public:
std::unordered_set<lpvar> collect_vars(const lemma& l) const;
bool rm_check(const monomial&) const;
bool rm_check(const monic&) const;
std::unordered_map<unsigned, unsigned_vector> get_rm_by_arity();
void add_abs_bound(lpvar v, llc cmp);
void add_abs_bound(lpvar v, llc cmp, rational const& bound);
bool find_bfc_to_refine_on_monomial(const monomial&, factorization & bf);
bool find_bfc_to_refine_on_monic(const monic&, factorization & bf);
bool find_bfc_to_refine(const monomial* & m, factorization& bf);
bool find_bfc_to_refine(const monic* & m, factorization& bf);
void negate_relation(unsigned j, const rational& a);
bool conflict_found() const;
@ -381,18 +381,18 @@ public:
struct pp_mon {
core const& c;
monomial const& m;
pp_mon(core const& c, monomial const& m): c(c), m(m) {}
monic const& m;
pp_mon(core const& c, monic const& m): c(c), m(m) {}
pp_mon(core const& c, lpvar v): c(c), m(c.emons()[v]) {}
};
struct pp_mon_with_vars {
core const& c;
monomial const& m;
pp_mon_with_vars(core const& c, monomial const& m): c(c), m(m) {}
monic const& m;
pp_mon_with_vars(core const& c, monic const& m): c(c), m(m) {}
pp_mon_with_vars(core const& c, lpvar v): c(c), m(c.emons()[v]) {}
};
inline std::ostream& operator<<(std::ostream& out, pp_mon const& p) { return p.c.print_monomial(p.m, out); }
inline std::ostream& operator<<(std::ostream& out, pp_mon_with_vars const& p) { return p.c.print_monomial_with_vars(p.m, out); }
inline std::ostream& operator<<(std::ostream& out, pp_mon const& p) { return p.c.print_monic(p.m, out); }
inline std::ostream& operator<<(std::ostream& out, pp_mon_with_vars const& p) { return p.c.print_monic_with_vars(p.m, out); }
struct pp_fac {
core const& c;

View file

@ -63,11 +63,11 @@ inline std::ostream& operator<<(std::ostream& out, signed_var const& sv) { retur
* represents definition m_v = coeff* v1*v2*...*vn,
* where m_vs = [v1, v2, .., vn]
*/
class monomial_coeff {
class monic_coeff {
svector<lp::var_index> m_vs;
rational m_coeff;
public:
monomial_coeff(const svector<lp::var_index>& vs, rational const& coeff): m_vs(vs), m_coeff(coeff) {}
monic_coeff(const svector<lp::var_index>& vs, rational const& coeff): m_vs(vs), m_coeff(coeff) {}
rational const& coeff() const { return m_coeff; }
const svector<lp::var_index> & vars() const { return m_vs; }
};

View file

@ -38,10 +38,10 @@ void nla_grobner::add_var_and_its_factors_to_q_and_collect_new_rows(lpvar j, std
}
}
if (!c().is_monomial_var(j))
if (!c().is_monic_var(j))
return;
const monomial& m = c().emons()[j];
const monic& m = c().emons()[j];
for (auto fcn : factorization_factory_imp(m, c())) {
for (const factor& fc: fcn) {
lpvar j = var(fc);
@ -71,7 +71,7 @@ var_weight nla_grobner::get_var_weight(lpvar j) const {
UNREACHABLE();
break;
}
if (c().is_monomial_var(j)) {
if (c().is_monic_var(j)) {
return (var_weight)((int)k + 1);
}
return k;
@ -88,7 +88,7 @@ void nla_grobner::find_nl_cluster() {
prepare_rows_and_active_vars();
std::queue<lpvar> q;
for (lpvar j : c().m_to_refine) {
TRACE("nla_grobner", c().print_monomial(c().emons()[j], tout) << "\n";);
TRACE("nla_grobner", c().print_monic(c().emons()[j], tout) << "\n";);
q.push(j);
}

View file

@ -35,6 +35,8 @@ struct grobner_stats {
grobner_stats() { reset(); }
};
struct monomial {
};
class equation {
unsigned m_scope_lvl; //!< scope level when this equation was created.

View file

@ -50,8 +50,8 @@ void monotone::negate_abs_a_le_abs_b(lpvar a, lpvar b, bool strict) {
}
void monotone::assert_abs_val_a_le_abs_var_b(
const monomial& a,
const monomial& b,
const monic& a,
const monic& b,
bool strict) {
lpvar aj = var(a);
lpvar bj = var(b);
@ -77,8 +77,8 @@ void monotone::negate_abs_a_lt_abs_b(lpvar a, lpvar b) {
mk_ineq(as, a, -bs, b, llc::GE); // negate |aj| < |bj|
}
void monotone::monotonicity_lemma(monomial const& m) {
SASSERT(!check_monomial(m));
void monotone::monotonicity_lemma(monic const& m) {
SASSERT(!check_monic(m));
if (c().mon_has_zero(m.vars()))
return;
const rational prod_val = abs(c().product_value(m.vars()));
@ -89,7 +89,7 @@ void monotone::monotonicity_lemma(monomial const& m) {
monotonicity_lemma_gt(m, prod_val);
}
void monotone::monotonicity_lemma_gt(const monomial& m, const rational& prod_val) {
void monotone::monotonicity_lemma_gt(const monic& m, const rational& prod_val) {
TRACE("nla_solver", tout << "prod_val = " << prod_val << "\n";);
add_empty_lemma();
for (lpvar j : m.vars()) {
@ -106,7 +106,7 @@ void monotone::monotonicity_lemma_gt(const monomial& m, const rational& prod_val
<=>
\/_i |m[i]| < |val(m[i])} or |m| >= |product_i val(m[i])|
*/
void monotone::monotonicity_lemma_lt(const monomial& m, const rational& prod_val) {
void monotone::monotonicity_lemma_lt(const monic& m, const rational& prod_val) {
add_empty_lemma();
for (lpvar j : m.vars()) {
c().add_abs_bound(j, llc::LT);

View file

@ -25,13 +25,13 @@ public:
monotone(core *core);
void monotonicity_lemma();
private:
void monotonicity_lemma(monomial const& m);
void monotonicity_lemma_gt(const monomial& m, const rational& prod_val);
void monotonicity_lemma_lt(const monomial& m, const rational& prod_val);
std::vector<rational> get_sorted_key(const monomial& rm) const;
vector<std::pair<rational, lpvar>> get_sorted_key_with_rvars(const monomial& a) const;
void monotonicity_lemma(monic const& m);
void monotonicity_lemma_gt(const monic& m, const rational& prod_val);
void monotonicity_lemma_lt(const monic& m, const rational& prod_val);
std::vector<rational> get_sorted_key(const monic& rm) const;
vector<std::pair<rational, lpvar>> get_sorted_key_with_rvars(const monic& a) const;
void negate_abs_a_le_abs_b(lpvar a, lpvar b, bool strict);
void negate_abs_a_lt_abs_b(lpvar a, lpvar b);
void assert_abs_val_a_le_abs_var_b(const monomial& a, const monomial& b, bool strict);
void assert_abs_val_a_le_abs_var_b(const monic& a, const monic& b, bool strict);
};
}

View file

@ -38,7 +38,7 @@ void order::order_lemma() {
unsigned sz = to_ref.size();
for (unsigned i = 0; i < sz && !done(); ++i) {
lpvar j = to_ref[(i + r) % sz];
order_lemma_on_monomial(c().emons()[j]);
order_lemma_on_monic(c().emons()[j]);
}
}
@ -46,7 +46,7 @@ void order::order_lemma() {
// a > b && c > 0 => ac > bc
// Consider here some binary factorizations of m=ac and
// try create order lemmas with either factor playing the role of c.
void order::order_lemma_on_monomial(const monomial& m) {
void order::order_lemma_on_monic(const monic& m) {
TRACE("nla_solver_details",
tout << "m = " << pp_mon(c(), m););
@ -61,13 +61,13 @@ void order::order_lemma_on_monomial(const monomial& m) {
break;
}
}
// Here ac is a monomial of size 2
// Here ac is a monic of size 2
// Trying to get an order lemma is
// a > b && c > 0 => ac > bc,
// with either variable of ac playing the role of c
void order::order_lemma_on_binomial(const monomial& ac) {
void order::order_lemma_on_binomial(const monic& ac) {
TRACE("nla_solver", tout << pp_mon_with_vars(c(), ac););
SASSERT(!check_monomial(ac) && ac.size() == 2);
SASSERT(!check_monic(ac) && ac.size() == 2);
const rational mult_val = val(ac.vars()[0]) * val(ac.vars()[1]);
const rational acv = val(ac);
bool gt = acv > mult_val;
@ -89,7 +89,7 @@ void order::order_lemma_on_binomial(const monomial& ac) {
y >= 0 or x > a or xy >= ay
*/
void order::order_lemma_on_binomial_sign(const monomial& xy, lpvar x, lpvar y, int sign) {
void order::order_lemma_on_binomial_sign(const monic& xy, lpvar x, lpvar y, int sign) {
SASSERT(!_().mon_has_zero(xy.vars()));
int sy = rat_sign(val(y));
add_empty_lemma();
@ -99,13 +99,13 @@ void order::order_lemma_on_binomial_sign(const monomial& xy, lpvar x, lpvar y, i
TRACE("nla_solver", print_lemma(tout););
}
// We look for monomials e = m.rvars()[k]*d and see if we can create an order lemma for m and e
void order::order_lemma_on_factor_binomial_explore(const monomial& ac, bool k) {
// We look for monics e = m.rvars()[k]*d and see if we can create an order lemma for m and e
void order::order_lemma_on_factor_binomial_explore(const monic& ac, bool k) {
TRACE("nla_solver", tout << "ac = " << pp_mon_with_vars(c(), ac););
SASSERT(ac.size() == 2);
lpvar c = ac.vars()[k];
for (monomial const& bd : _().emons().get_products_of(c)) {
for (monic const& bd : _().emons().get_products_of(c)) {
if (bd.var() == ac.var()) continue;
TRACE("nla_solver", tout << "bd = " << pp_mon_with_vars(_(), bd););
order_lemma_on_factor_binomial_rm(ac, k, bd);
@ -116,8 +116,8 @@ void order::order_lemma_on_factor_binomial_explore(const monomial& ac, bool k) {
}
// ac is a binomial
// create order lemma on monomials bd where d is equivalent to ac[k]
void order::order_lemma_on_factor_binomial_rm(const monomial& ac, bool k, const monomial& bd) {
// create order lemma on monics bd where d is equivalent to ac[k]
void order::order_lemma_on_factor_binomial_rm(const monic& ac, bool k, const monic& bd) {
TRACE("nla_solver",
tout << "ac=" << pp_mon_with_vars(_(), ac) << "\n";
tout << "k=" << k << "\n";
@ -131,7 +131,7 @@ void order::order_lemma_on_factor_binomial_rm(const monomial& ac, bool k, const
}
// ac >= bd && |c| = |d| => ac/|c| >= bd/|d|
void order::order_lemma_on_binomial_ac_bd(const monomial& ac, bool k, const monomial& bd, const factor& b, lpvar d) {
void order::order_lemma_on_binomial_ac_bd(const monic& ac, bool k, const monic& bd, const factor& b, lpvar d) {
lpvar a = ac.vars()[!k];
lpvar c = ac.vars()[k];
TRACE("nla_solver",
@ -162,11 +162,11 @@ void order::order_lemma_on_binomial_ac_bd(const monomial& ac, bool k, const mono
// c and d are equivalent |c| == |d|
// ac > bd => ac/|c| > bd/|d| => a*c_sign > b*d_sign
// but the last inequality does not hold
void order::generate_mon_ol(const monomial& ac,
void order::generate_mon_ol(const monic& ac,
lpvar a,
const rational& c_sign,
lpvar c,
const monomial& bd,
const monic& bd,
const factor& b,
const rational& d_sign,
lpvar d,
@ -199,10 +199,10 @@ void order::generate_mon_ol(const monomial& ac,
// a >< b && c < 0 => ac <> bc
// ac[k] plays the role of c
bool order::order_lemma_on_ac_and_bc(const monomial& rm_ac,
bool order::order_lemma_on_ac_and_bc(const monic& rm_ac,
const factorization& ac_f,
bool k,
const monomial& rm_bd) {
const monic& rm_bd) {
TRACE("nla_solver",
tout << "rm_ac = " << pp_mon_with_vars(_(), rm_ac) << "\n";
tout << "rm_bd = " << pp_mon_with_vars(_(), rm_bd) << "\n";
@ -216,9 +216,9 @@ bool order::order_lemma_on_ac_and_bc(const monomial& rm_ac,
// Here ab is a binary factorization of m.
// We try to find a monomial n = cd, such that |b| = |d|
// We try to find a monic n = cd, such that |b| = |d|
// and get a lemma m R n & |b| = |d| => ab/|b| R cd /|d|, where R is a relation
void order::order_lemma_on_factorization(const monomial& m, const factorization& ab) {
void order::order_lemma_on_factorization(const monic& m, const factorization& ab) {
bool sign = m.rsign();
for (factor f: ab)
sign ^= _().canonize_sign(f);
@ -230,7 +230,7 @@ void order::order_lemma_on_factorization(const monomial& m, const factorization&
if (mv == fv)
return;
bool gt = mv > fv;
TRACE("nla_solver", tout << "m="; _().print_monomial_with_vars(m, tout); tout << "\nfactorization="; _().print_factorization(ab, tout););
TRACE("nla_solver", tout << "m="; _().print_monic_with_vars(m, tout); tout << "\nfactorization="; _().print_factorization(ab, tout););
for (unsigned j = 0, k = 1; j < 2; j++, k--) {
order_lemma_on_ab(m, sign_to_rat(sign), var(ab[k]), var(ab[j]), gt);
explain(ab); explain(m);
@ -239,19 +239,19 @@ void order::order_lemma_on_factorization(const monomial& m, const factorization&
}
}
bool order::order_lemma_on_ac_explore(const monomial& rm, const factorization& ac, bool k) {
bool order::order_lemma_on_ac_explore(const monic& rm, const factorization& ac, bool k) {
const factor c = ac[k];
TRACE("nla_solver", tout << "c = "; _().print_factor_with_vars(c, tout); );
if (c.is_var()) {
TRACE("nla_solver", tout << "var(c) = " << var(c););
for (monomial const& bc : _().emons().get_use_list(c.var())) {
for (monic const& bc : _().emons().get_use_list(c.var())) {
if (order_lemma_on_ac_and_bc(rm ,ac, k, bc)) {
return true;
}
}
}
else {
for (monomial const& bc : _().emons().get_products_of(c.var())) {
for (monic const& bc : _().emons().get_products_of(c.var())) {
if (order_lemma_on_ac_and_bc(rm , ac, k, bc)) {
return true;
}
@ -262,11 +262,11 @@ bool order::order_lemma_on_ac_explore(const monomial& rm, const factorization& a
// |c_sign| = 1, and c*c_sign > 0
// ac > bc => ac/|c| > bc/|c| => a*c_sign > b*c_sign
void order::generate_ol(const monomial& ac,
void order::generate_ol(const monic& ac,
const factor& a,
int c_sign,
const factor& c,
const monomial& bc,
const monic& bc,
const factor& b,
llc ab_cmp) {
add_empty_lemma();
@ -282,10 +282,10 @@ void order::generate_ol(const monomial& ac,
TRACE("nla_solver", _().print_lemma(tout););
}
bool order::order_lemma_on_ac_and_bc_and_factors(const monomial& ac,
bool order::order_lemma_on_ac_and_bc_and_factors(const monic& ac,
const factor& a,
const factor& c,
const monomial& bc,
const monic& bc,
const factor& b) {
auto cv = val(c);
int c_sign = nla::rat_sign(cv);
@ -311,7 +311,7 @@ bool order::order_lemma_on_ac_and_bc_and_factors(const monomial& ac,
a > 0 & b <= value(b) => sign*ab <= value(b)*a if value(a) > 0
a < 0 & b >= value(b) => sign*ab <= value(b)*a if value(a) < 0
*/
void order::order_lemma_on_ab_gt(const monomial& m, const rational& sign, lpvar a, lpvar b) {
void order::order_lemma_on_ab_gt(const monic& m, const rational& sign, lpvar a, lpvar b) {
SASSERT(sign * val(m) > val(a) * val(b));
add_empty_lemma();
if (val(a).is_pos()) {
@ -339,7 +339,7 @@ void order::order_lemma_on_ab_gt(const monomial& m, const rational& sign, lpvar
a > 0 & b >= value(b) => sign*ab >= value(b)*a if value(a) > 0
a < 0 & b <= value(b) => sign*ab >= value(b)*a if value(a) < 0
*/
void order::order_lemma_on_ab_lt(const monomial& m, const rational& sign, lpvar a, lpvar b) {
void order::order_lemma_on_ab_lt(const monic& m, const rational& sign, lpvar a, lpvar b) {
SASSERT(sign * val(m) < val(a) * val(b));
add_empty_lemma();
if (val(a).is_pos()) {
@ -360,7 +360,7 @@ void order::order_lemma_on_ab_lt(const monomial& m, const rational& sign, lpvar
}
}
void order::order_lemma_on_ab(const monomial& m, const rational& sign, lpvar a, lpvar b, bool gt) {
void order::order_lemma_on_ab(const monic& m, const rational& sign, lpvar a, lpvar b, bool gt) {
if (gt)
order_lemma_on_ab_gt(m, sign, a, b);
else

View file

@ -30,59 +30,59 @@ public:
private:
bool order_lemma_on_ac_and_bc_and_factors(const monomial& ac,
bool order_lemma_on_ac_and_bc_and_factors(const monic& ac,
const factor& a,
const factor& c,
const monomial& bc,
const monic& bc,
const factor& b);
// a >< b && c > 0 => ac >< bc
// a >< b && c < 0 => ac <> bc
// ac[k] plays the role of c
bool order_lemma_on_ac_and_bc(const monomial& rm_ac,
bool order_lemma_on_ac_and_bc(const monic& rm_ac,
const factorization& ac_f,
bool k,
const monomial& rm_bd);
const monic& rm_bd);
bool order_lemma_on_ac_explore(const monomial& rm, const factorization& ac, bool k);
bool order_lemma_on_ac_explore(const monic& rm, const factorization& ac, bool k);
void order_lemma_on_factorization(const monomial& rm, const factorization& ab);
void order_lemma_on_factorization(const monic& rm, const factorization& ab);
/**
\brief Add lemma:
a > 0 & b <= value(b) => sign*ab <= value(b)*a if value(a) > 0
a < 0 & b >= value(b) => sign*ab <= value(b)*a if value(a) < 0
*/
void order_lemma_on_ab_gt(const monomial& m, const rational& sign, lpvar a, lpvar b);
void order_lemma_on_ab_gt(const monic& m, const rational& sign, lpvar a, lpvar b);
// we need to deduce ab >= val(b)*a
/**
\brief Add lemma:
a > 0 & b >= value(b) => sign*ab >= value(b)*a if value(a) > 0
a < 0 & b <= value(b) => sign*ab >= value(b)*a if value(a) < 0
*/
void order_lemma_on_ab_lt(const monomial& m, const rational& sign, lpvar a, lpvar b);
void order_lemma_on_ab(const monomial& m, const rational& sign, lpvar a, lpvar b, bool gt);
void order_lemma_on_factor_binomial_explore(const monomial& m, bool k);
void order_lemma_on_factor_binomial_rm(const monomial& ac, bool k, const monomial& bd);
void order_lemma_on_binomial_ac_bd(const monomial& ac, bool k, const monomial& bd, const factor& b, lpvar d);
void order_lemma_on_binomial_sign(const monomial& ac, lpvar x, lpvar y, int sign);
void order_lemma_on_binomial(const monomial& ac);
void order_lemma_on_monomial(const monomial& rm);
void order_lemma_on_ab_lt(const monic& m, const rational& sign, lpvar a, lpvar b);
void order_lemma_on_ab(const monic& m, const rational& sign, lpvar a, lpvar b, bool gt);
void order_lemma_on_factor_binomial_explore(const monic& m, bool k);
void order_lemma_on_factor_binomial_rm(const monic& ac, bool k, const monic& bd);
void order_lemma_on_binomial_ac_bd(const monic& ac, bool k, const monic& bd, const factor& b, lpvar d);
void order_lemma_on_binomial_sign(const monic& ac, lpvar x, lpvar y, int sign);
void order_lemma_on_binomial(const monic& ac);
void order_lemma_on_monic(const monic& rm);
// |c_sign| = 1, and c*c_sign > 0
// ac > bc => ac/|c| > bc/|c| => a*c_sign > b*c_sign
void generate_ol(const monomial& ac,
void generate_ol(const monic& ac,
const factor& a,
int c_sign,
const factor& c,
const monomial& bc,
const monic& bc,
const factor& b,
llc ab_cmp);
void generate_mon_ol(const monomial& ac,
void generate_mon_ol(const monic& ac,
lpvar a,
const rational& c_sign,
lpvar c,
const monomial& bd,
const monic& bd,
const factor& b,
const rational& d_sign,
lpvar d,

View file

@ -19,19 +19,19 @@
--*/
#include "math/lp/nla_solver.h"
#include <map>
#include "math/lp/monomial.h"
#include "math/lp/monic.h"
#include "math/lp/lp_utils.h"
#include "math/lp/var_eqs.h"
#include "math/lp/factorization.h"
#include "math/lp/nla_solver.h"
namespace nla {
void solver::add_monomial(lpvar v, unsigned sz, lpvar const* vs) {
m_core->add_monomial(v, sz, vs);
void solver::add_monic(lpvar v, unsigned sz, lpvar const* vs) {
m_core->add_monic(v, sz, vs);
}
bool solver::is_monomial_var(lpvar v) const {
return m_core->is_monomial_var(v);
bool solver::is_monic_var(lpvar v) const {
return m_core->is_monic_var(v);
}
bool solver::need_check() { return true; }

View file

@ -24,7 +24,7 @@ Revision History:
#include "util/params.h"
#include "nlsat/nlsat_solver.h"
#include "math/lp/lar_solver.h"
#include "math/lp/monomial.h"
#include "math/lp/monic.h"
#include "math/lp/nla_core.h"
namespace nla {
@ -34,7 +34,7 @@ class solver {
reslimit m_res_limit;
core* m_core;
public:
void add_monomial(lpvar v, unsigned sz, lpvar const* vs);
void add_monic(lpvar v, unsigned sz, lpvar const* vs);
solver(lp::lar_solver& s);
~solver();
@ -43,6 +43,6 @@ public:
void pop(unsigned scopes);
bool need_check();
lbool check(vector<lemma>&);
bool is_monomial_var(lpvar) const;
bool is_monic_var(lpvar) const;
};
}

View file

@ -35,13 +35,13 @@ void tangents::tangent_lemma() {
return;
}
factorization bf(nullptr);
const monomial* m;
const monic* m;
if (c().find_bfc_to_refine(m, bf)) {
tangent_lemma_bf(*m, bf);
}
}
void tangents::generate_explanations_of_tang_lemma(const monomial& rm, const factorization& bf, lp::explanation& exp) {
void tangents::generate_explanations_of_tang_lemma(const monic& rm, const factorization& bf, lp::explanation& exp) {
// here we repeat the same explanation for each lemma
c().explain(rm, exp);
c().explain(bf[0], exp);
@ -69,7 +69,7 @@ void tangents::generate_tang_plane(const rational & a, const rational& b, const
c().mk_ineq(t, below? llc::GT : llc::LT, - a*b);
}
void tangents::tangent_lemma_bf(const monomial& m, const factorization& bf){
void tangents::tangent_lemma_bf(const monic& m, const factorization& bf){
point a, b;
point xy (val(bf[0]), val(bf[1]));
rational correct_mult_val = xy.x * xy.y;

View file

@ -53,9 +53,9 @@ public:
void tangent_lemma();
private:
lpvar find_binomial_to_refine();
void generate_explanations_of_tang_lemma(const monomial& m, const factorization& bf, lp::explanation& exp);
void generate_simple_tangent_lemma(const monomial& m, const factorization&);
void tangent_lemma_bf(const monomial& m,const factorization& bf);
void generate_explanations_of_tang_lemma(const monic& m, const factorization& bf, lp::explanation& exp);
void generate_simple_tangent_lemma(const monic& m, const factorization&);
void tangent_lemma_bf(const monic& m,const factorization& bf);
void generate_tang_plane(const rational & a, const rational& b, const factor& x, const factor& y, bool below, lpvar j);
void generate_two_tang_lines(const factorization & bf, const point& xy, lpvar j);

View file

@ -9,7 +9,7 @@
#include "math/polynomial/polynomial.h"
#include "math/polynomial/algebraic_numbers.h"
#include "util/map.h"
#include "math/lp/monomial.h"
#include "math/lp/monic.h"
namespace nra {
@ -23,8 +23,8 @@ typedef nla::variable_map_type variable_map_type;
u_map<polynomial::var> m_lp2nl; // map from lar_solver variables to nlsat::solver variables
scoped_ptr<nlsat::solver> m_nlsat;
scoped_ptr<scoped_anum> m_zero;
vector<mon_eq> m_monomials;
unsigned_vector m_monomials_lim;
vector<mon_eq> m_monics;
unsigned_vector m_monics_lim;
mutable variable_map_type m_variable_values; // current model
imp(lp::lar_solver& s, reslimit& lim, params_ref const& p):
@ -34,21 +34,21 @@ typedef nla::variable_map_type variable_map_type;
}
bool need_check() {
return !m_monomials.empty() && !check_assignments(m_monomials, s, m_variable_values);
return !m_monics.empty() && !check_assignments(m_monics, s, m_variable_values);
}
void add(lp::var_index v, unsigned sz, lp::var_index const* vs) {
m_monomials.push_back(mon_eq(v, sz, vs));
m_monics.push_back(mon_eq(v, sz, vs));
}
void push() {
m_monomials_lim.push_back(m_monomials.size());
m_monics_lim.push_back(m_monics.size());
}
void pop(unsigned n) {
if (n == 0) return;
m_monomials.shrink(m_monomials_lim[m_monomials_lim.size() - n]);
m_monomials_lim.shrink(m_monomials_lim.size() - n);
m_monics.shrink(m_monics_lim[m_monics_lim.size() - n]);
m_monics_lim.shrink(m_monics_lim.size() - n);
}
/*
@ -67,7 +67,7 @@ typedef nla::variable_map_type variable_map_type;
bool check_assignments() const {
s.get_model(m_variable_values);
for (auto const& m : m_monomials) {
for (auto const& m : m_monics) {
if (!check_assignment(m)) return false;
}
return true;
@ -97,8 +97,8 @@ typedef nla::variable_map_type variable_map_type;
}
// add polynomial definitions.
for (auto const& m : m_monomials) {
add_monomial_eq(m);
for (auto const& m : m_monics) {
add_monic_eq(m);
}
// TBD: add variable bounds?
@ -134,7 +134,7 @@ typedef nla::variable_map_type variable_map_type;
return r;
}
void add_monomial_eq(mon_eq const& m) {
void add_monic_eq(mon_eq const& m) {
polynomial::manager& pm = m_nlsat->pm();
svector<polynomial::var> vars;
for (auto v : m.vars()) {
@ -142,7 +142,7 @@ typedef nla::variable_map_type variable_map_type;
}
polynomial::monomial_ref m1(pm.mk_monomial(vars.size(), vars.c_ptr()), pm);
polynomial::monomial_ref m2(pm.mk_monomial(lp2nl(m.var()), 1), pm);
polynomial::monomial* mls[2] = { m1, m2 };
polynomial::monomial * mls[2] = { m1, m2 };
polynomial::scoped_numeral_vector coeffs(pm.m());
coeffs.push_back(mpz(1));
coeffs.push_back(mpz(-1));
@ -226,7 +226,7 @@ typedef nla::variable_map_type variable_map_type;
}
std::ostream& display(std::ostream& out) const {
for (auto m : m_monomials) {
for (auto m : m_monics) {
out << "v" << m.var() << " = ";
for (auto v : m.vars()) {
out << "v" << v << " ";
@ -245,7 +245,7 @@ typedef nla::variable_map_type variable_map_type;
dealloc(m_imp);
}
void solver::add_monomial(lp::var_index v, unsigned sz, lp::var_index const* vs) {
void solver::add_monic(lp::var_index v, unsigned sz, lp::var_index const* vs) {
m_imp->add(v, sz, vs);
}

View file

@ -33,7 +33,7 @@ namespace nra {
\brief Add a definition v = vs[0]*vs[1]*...*vs[sz-1]
The variable v is equal to the product of variables vs.
*/
void add_monomial(lp::var_index v, unsigned sz, lp::var_index const* vs);
void add_monic(lp::var_index v, unsigned sz, lp::var_index const* vs);
/*
\brief Check feasiblity of linear constraints augmented by polynomial definitions

View file

@ -308,14 +308,14 @@ class theory_lra::imp {
}
void add_monomial(lpvar v, unsigned sz, lpvar const* vs) {
void add_monic(lpvar v, unsigned sz, lpvar const* vs) {
if (m_use_nla) {
m_th_imp.ensure_nla();
(*m_nla)->add_monomial(v, sz, vs);
(*m_nla)->add_monic(v, sz, vs);
}
else {
m_th_imp.ensure_nra();
(*m_nra)->add_monomial(v, sz, vs);
(*m_nra)->add_monic(v, sz, vs);
}
}
@ -658,7 +658,7 @@ class theory_lra::imp {
m_solver->m_need_register_terms = true;
m_solver->register_existing_terms();
}
m_switcher.add_monomial(register_theory_var_in_lar_solver(v), vars.size(), vars.c_ptr());
m_switcher.add_monic(register_theory_var_in_lar_solver(v), vars.size(), vars.c_ptr());
}
}