mirror of
https://github.com/Z3Prover/z3
synced 2025-10-26 17:29:21 +00:00
fixing factoring and hitting NOT_IMPLEMENTED on ir_ord
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
7049eab658
commit
49eb5625ca
5 changed files with 51 additions and 38 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
z3_add_component(nlsat
|
z3_add_component(nlsat
|
||||||
SOURCES
|
SOURCES
|
||||||
nlsat_clause.cpp
|
nlsat_clause.cpp
|
||||||
|
nlsat_common.cpp
|
||||||
nlsat_evaluator.cpp
|
nlsat_evaluator.cpp
|
||||||
nlsat_explain.cpp
|
nlsat_explain.cpp
|
||||||
nlsat_interval_set.cpp
|
nlsat_interval_set.cpp
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
#include "math/polynomial/algebraic_numbers.h"
|
#include "math/polynomial/algebraic_numbers.h"
|
||||||
#include "nlsat_common.h"
|
#include "nlsat_common.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include "math/polynomial/polynomial_cache.h"
|
||||||
|
#include "math/polynomial/polynomial.h"
|
||||||
|
|
||||||
namespace nlsat {
|
namespace nlsat {
|
||||||
|
|
||||||
|
|
@ -30,17 +32,22 @@ namespace nlsat {
|
||||||
struct levelwise::impl {
|
struct levelwise::impl {
|
||||||
// Utility: call fn for each distinct irreducible factor of poly
|
// Utility: call fn for each distinct irreducible factor of poly
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
void for_each_distinct_factor(const polynomial::polynomial_ref& poly, Func&& fn) {
|
void for_each_distinct_factor(polynomial::polynomial_ref& poly, Func&& fn) {
|
||||||
polynomial::factors factors(m_pm);
|
polynomial::polynomial_ref_vector factors(m_pm);
|
||||||
factor(poly, factors);
|
::nlsat::factor(poly, m_cache, factors);
|
||||||
for (unsigned i = 0; i < factors.distinct_factors(); ++i)
|
for (unsigned i = 0; i < factors.size(); i++) {
|
||||||
fn(factors[i]);
|
polynomial_ref pr(m_pm);
|
||||||
|
pr = factors.get(i);
|
||||||
|
fn(pr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
template<typename Func>
|
template<typename Func>
|
||||||
void for_first_distinct_factor(const polynomial::polynomial_ref& poly, Func&& fn) {
|
void for_first_distinct_factor(polynomial::polynomial_ref& poly, Func&& fn) {
|
||||||
polynomial::factors factors(m_pm);
|
polynomial::polynomial_ref_vector factors(m_pm);
|
||||||
factor(poly, factors);
|
::nlsat::factor(poly, m_cache, factors);
|
||||||
fn(factors[0]);
|
polynomial_ref pr(m_pm);
|
||||||
|
pr = factors.get(0);
|
||||||
|
fn(pr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: consider to key polynomials in a set by using m_pm.eq
|
// todo: consider to key polynomials in a set by using m_pm.eq
|
||||||
|
|
@ -98,11 +105,11 @@ namespace nlsat {
|
||||||
std::vector<root_function> m_E; // the ordered root functions on a level
|
std::vector<root_function> m_E; // the ordered root functions on a level
|
||||||
assignment const & sample() const { return m_solver.sample();}
|
assignment const & sample() const { return m_solver.sample();}
|
||||||
assignment & sample() { return m_solver.sample(); }
|
assignment & sample() { return m_solver.sample(); }
|
||||||
|
polynomial::cache & m_cache;
|
||||||
// max_x plays the role of n in algorith 1 of the levelwise paper.
|
// max_x plays the role of n in algorith 1 of the levelwise paper.
|
||||||
|
|
||||||
impl(solver& solver, polynomial_ref_vector const& ps, var max_x, assignment const& s, pmanager& pm, anum_manager& am)
|
impl(solver& solver, polynomial_ref_vector const& ps, var max_x, assignment const& s, pmanager& pm, anum_manager& am, polynomial::cache & cache)
|
||||||
: m_solver(solver), m_P(ps), m_n(max_x), m_pm(pm), m_am(am) {
|
: m_solver(solver), m_P(ps), m_n(max_x), m_pm(pm), m_am(am), m_cache(cache) {
|
||||||
TRACE(lws, tout << "m_n:" << m_n << "\n";);
|
TRACE(lws, tout << "m_n:" << m_n << "\n";);
|
||||||
m_I.reserve(m_n); // cannot just resize bcs of the absence of the default constructor of root_function_interval
|
m_I.reserve(m_n); // cannot just resize bcs of the absence of the default constructor of root_function_interval
|
||||||
for (unsigned i = 0; i < m_n; ++i)
|
for (unsigned i = 0; i < m_n; ++i)
|
||||||
|
|
@ -136,9 +143,18 @@ namespace nlsat {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_irreducible(poly* p) {
|
bool is_irreducible(poly* p) {
|
||||||
polynomial::factors factors(m_pm);
|
polynomial_ref_vector factors(m_pm);
|
||||||
factor(polynomial_ref(p, m_pm), factors);
|
polynomial_ref pref(p, m_pm);
|
||||||
return factors.total_factors() == 1;
|
::nlsat::factor(pref, m_cache, factors);
|
||||||
|
unsigned num_factors = factors.size();
|
||||||
|
CTRACE(lws, num_factors != 1, ::nlsat::display(tout, m_solver, p) << std::endl;
|
||||||
|
tout << "{";
|
||||||
|
tout << "num_factors:" << num_factors << "\n";
|
||||||
|
::nlsat::display(tout, m_solver, factors);
|
||||||
|
tout << "}\n";
|
||||||
|
);
|
||||||
|
|
||||||
|
return factors.size() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -338,6 +354,7 @@ namespace nlsat {
|
||||||
}
|
}
|
||||||
|
|
||||||
collect_E(p_non_null);
|
collect_E(p_non_null);
|
||||||
|
|
||||||
std::sort(m_E.begin(), m_E.end(), [&](root_function const& a, root_function const& b){
|
std::sort(m_E.begin(), m_E.end(), [&](root_function const& a, root_function const& b){
|
||||||
return m_am.lt(a.val, b.val);
|
return m_am.lt(a.val, b.val);
|
||||||
});
|
});
|
||||||
|
|
@ -411,7 +428,6 @@ namespace nlsat {
|
||||||
for_each_distinct_factor(disc, [&](polynomial::polynomial_ref f) {
|
for_each_distinct_factor(disc, [&](polynomial::polynomial_ref f) {
|
||||||
if (coeffs_are_zeroes_on_sample(f, m_pm, sample(), m_am)) {
|
if (coeffs_are_zeroes_on_sample(f, m_pm, sample(), m_am)) {
|
||||||
m_fail = true; // ambiguous multiplicity -- not handled yet
|
m_fail = true; // ambiguous multiplicity -- not handled yet
|
||||||
NOT_IMPLEMENTED_YET();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
unsigned lvl = max_var(f);
|
unsigned lvl = max_var(f);
|
||||||
|
|
@ -714,6 +730,7 @@ or
|
||||||
*/
|
*/
|
||||||
mk_prop(sample_holds, level_t(m_level - 1));
|
mk_prop(sample_holds, level_t(m_level - 1));
|
||||||
mk_prop(repr, level_t(m_level - 1));
|
mk_prop(repr, level_t(m_level - 1));
|
||||||
|
mk_prop(ir_ord, level_t(m_level));
|
||||||
mk_prop(an_del, p.poly);
|
mk_prop(an_del, p.poly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -863,8 +880,8 @@ or
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// constructor
|
// constructor
|
||||||
levelwise::levelwise(nlsat::solver& solver, polynomial_ref_vector const& ps, var n, assignment const& s, pmanager& pm, anum_manager& am)
|
levelwise::levelwise(nlsat::solver& solver, polynomial_ref_vector const& ps, var n, assignment const& s, pmanager& pm, anum_manager& am, polynomial::cache& cache)
|
||||||
: m_impl(new impl(solver, ps, n, s, pm, am)) {}
|
: m_impl(new impl(solver, ps, n, s, pm, am, cache)) {}
|
||||||
|
|
||||||
levelwise::~levelwise() { delete m_impl; }
|
levelwise::~levelwise() { delete m_impl; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "nlsat_types.h"
|
#include "nlsat_types.h"
|
||||||
|
#include "math/polynomial/polynomial_cache.h"
|
||||||
|
|
||||||
namespace nlsat {
|
namespace nlsat {
|
||||||
|
|
||||||
|
|
@ -39,7 +40,7 @@ namespace nlsat {
|
||||||
impl* m_impl;
|
impl* m_impl;
|
||||||
public:
|
public:
|
||||||
// Construct with polynomials ps, maximal variable max_x, current sample s, polynomial manager pm, and algebraic-number manager am
|
// Construct with polynomials ps, maximal variable max_x, current sample s, polynomial manager pm, and algebraic-number manager am
|
||||||
levelwise(nlsat::solver& solver, polynomial_ref_vector const& ps, var max_x, assignment const& s, pmanager& pm, anum_manager& am);
|
levelwise(nlsat::solver& solver, polynomial_ref_vector const& ps, var max_x, assignment const& s, pmanager& pm, anum_manager& am, polynomial::cache & cache);
|
||||||
~levelwise();
|
~levelwise();
|
||||||
|
|
||||||
levelwise(levelwise const&) = delete;
|
levelwise(levelwise const&) = delete;
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,11 @@
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "nlsat/nlsat_assignment.h"
|
||||||
#include "nlsat/nlsat_solver.h"
|
#include "nlsat/nlsat_solver.h"
|
||||||
#include "nlsat/nlsat_scoped_literal_vector.h"
|
#include "nlsat/nlsat_scoped_literal_vector.h"
|
||||||
|
#include "math/polynomial/polynomial_cache.h"
|
||||||
|
|
||||||
namespace nlsat {
|
namespace nlsat {
|
||||||
|
|
||||||
inline std::ostream& display(std::ostream& out, pmanager& pm, polynomial_ref const& p, display_var_proc const& proc) {
|
inline std::ostream& display(std::ostream& out, pmanager& pm, polynomial_ref const& p, display_var_proc const& proc) {
|
||||||
|
|
@ -119,5 +122,9 @@ namespace nlsat {
|
||||||
out << '\n';
|
out << '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
\brief Wrapper for factorization
|
||||||
|
*/
|
||||||
|
void factor(polynomial_ref & p, polynomial::cache& cache, polynomial_ref_vector & fs);
|
||||||
|
|
||||||
} // namespace nlsat
|
} // namespace nlsat
|
||||||
|
|
|
||||||
|
|
@ -188,16 +188,6 @@ namespace nlsat {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
\brief Wrapper for factorization
|
|
||||||
*/
|
|
||||||
void factor(polynomial_ref & p, polynomial_ref_vector & fs) {
|
|
||||||
// TODO: add params, caching
|
|
||||||
TRACE(nlsat_factor, tout << "factor\n" << p << "\n";);
|
|
||||||
fs.reset();
|
|
||||||
m_cache.factor(p.get(), fs);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Wrapper for psc chain computation
|
\brief Wrapper for psc chain computation
|
||||||
*/
|
*/
|
||||||
|
|
@ -257,7 +247,7 @@ namespace nlsat {
|
||||||
// Then, I assert p_i1 * ... * p_im != 0
|
// Then, I assert p_i1 * ... * p_im != 0
|
||||||
{
|
{
|
||||||
restore_factors _restore(m_factors, m_factors_save);
|
restore_factors _restore(m_factors, m_factors_save);
|
||||||
factor(p, m_factors);
|
factor(p, m_cache, m_factors);
|
||||||
unsigned num_factors = m_factors.size();
|
unsigned num_factors = m_factors.size();
|
||||||
m_zero_fs.reset();
|
m_zero_fs.reset();
|
||||||
m_is_even.reset();
|
m_is_even.reset();
|
||||||
|
|
@ -576,7 +566,7 @@ namespace nlsat {
|
||||||
return;
|
return;
|
||||||
if (m_factor) {
|
if (m_factor) {
|
||||||
restore_factors _restore(m_factors, m_factors_save);
|
restore_factors _restore(m_factors, m_factors_save);
|
||||||
factor(p, m_factors);
|
factor(p, m_cache, m_factors);
|
||||||
TRACE(nlsat_explain, display(tout << "adding factors of\n", m_solver, p); tout << "\n" << m_factors << "\n";);
|
TRACE(nlsat_explain, display(tout << "adding factors of\n", m_solver, p); tout << "\n" << m_factors << "\n";);
|
||||||
polynomial_ref f(m_pm);
|
polynomial_ref f(m_pm);
|
||||||
for (unsigned i = 0; i < m_factors.size(); i++) {
|
for (unsigned i = 0; i < m_factors.size(); i++) {
|
||||||
|
|
@ -667,7 +657,7 @@ namespace nlsat {
|
||||||
// this function also explains the value 0, if met
|
// this function also explains the value 0, if met
|
||||||
bool coeffs_are_zeroes(polynomial_ref &s) {
|
bool coeffs_are_zeroes(polynomial_ref &s) {
|
||||||
restore_factors _restore(m_factors, m_factors_save);
|
restore_factors _restore(m_factors, m_factors_save);
|
||||||
factor(s, m_factors);
|
factor(s, m_cache, m_factors);
|
||||||
unsigned num_factors = m_factors.size();
|
unsigned num_factors = m_factors.size();
|
||||||
m_zero_fs.reset();
|
m_zero_fs.reset();
|
||||||
m_is_even.reset();
|
m_is_even.reset();
|
||||||
|
|
@ -1179,8 +1169,8 @@ namespace nlsat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool levelwise_single_cell(polynomial_ref_vector & ps, var max_x) {
|
bool levelwise_single_cell(polynomial_ref_vector & ps, var max_x, polynomial::cache & cache) {
|
||||||
levelwise lws(m_solver, ps, max_x, sample(), m_pm, m_am);
|
levelwise lws(m_solver, ps, max_x, sample(), m_pm, m_am, cache);
|
||||||
auto cell = lws.single_cell();
|
auto cell = lws.single_cell();
|
||||||
if (lws.failed()) {
|
if (lws.failed()) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1216,9 +1206,6 @@ namespace nlsat {
|
||||||
*/
|
*/
|
||||||
void project_cdcac(polynomial_ref_vector & ps, var max_x) {
|
void project_cdcac(polynomial_ref_vector & ps, var max_x) {
|
||||||
TRACE(nlsat_explain, tout << "max_x:" << max_x << std::endl;);
|
TRACE(nlsat_explain, tout << "max_x:" << max_x << std::endl;);
|
||||||
if (max_x == 0) {
|
|
||||||
std::cout << "*";
|
|
||||||
}
|
|
||||||
if (ps.empty()) {
|
if (ps.empty()) {
|
||||||
TRACE(nlsat_explain, tout << "ps.empty\n";);
|
TRACE(nlsat_explain, tout << "ps.empty\n";);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1238,7 +1225,7 @@ namespace nlsat {
|
||||||
var x = m_todo.extract_max_polys(ps);
|
var x = m_todo.extract_max_polys(ps);
|
||||||
|
|
||||||
TRACE(nlsat_explain, tout << "m_solver.apply_levelwise():" << m_solver.apply_levelwise() << "\n";);
|
TRACE(nlsat_explain, tout << "m_solver.apply_levelwise():" << m_solver.apply_levelwise() << "\n";);
|
||||||
if (m_solver.apply_levelwise() && levelwise_single_cell(ps, max_x))
|
if (m_solver.apply_levelwise() && levelwise_single_cell(ps, max_x, m_cache))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
polynomial_ref_vector samples(m_pm);
|
polynomial_ref_vector samples(m_pm);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue