diff --git a/src/nlsat/nlsat_solver.h b/src/nlsat/nlsat_solver.h index 3668629cd..08902e709 100644 --- a/src/nlsat/nlsat_solver.h +++ b/src/nlsat/nlsat_solver.h @@ -21,10 +21,10 @@ Revision History: #ifndef NLSAT_SOLVER_H_ #define NLSAT_SOLVER_H_ -#include"nlsat_types.h" -#include"params.h" -#include"statistics.h" -#include"rlimit.h" +#include"nlsat/nlsat_types.h" +#include"util/params.h" +#include"util/statistics.h" +#include"util/rlimit.h" namespace nlsat { diff --git a/src/nlsat/nlsat_types.h b/src/nlsat/nlsat_types.h index 11e063a17..70da98e32 100644 --- a/src/nlsat/nlsat_types.h +++ b/src/nlsat/nlsat_types.h @@ -19,10 +19,10 @@ Revision History: #ifndef NLSAT_TYPES_H_ #define NLSAT_TYPES_H_ -#include"polynomial.h" -#include"buffer.h" -#include"sat_types.h" -#include"z3_exception.h" +#include"math/polynomial/polynomial.h" +#include"util/buffer.h" +#include"sat/sat_types.h" +#include"util/z3_exception.h" namespace algebraic_numbers { class anum; diff --git a/src/util/lp/nra_solver.cpp b/src/util/lp/nra_solver.cpp index 08b17030c..6ccc73633 100644 --- a/src/util/lp/nra_solver.cpp +++ b/src/util/lp/nra_solver.cpp @@ -5,18 +5,28 @@ #pragma once #include "util/lp/nra_solver.h" +#include "nlsat/nlsat_solver.h" namespace lp { struct nra_solver::imp { lean::lar_solver& s; + reslimit m_limit; // TBD: extract from lar_solver + params_ref m_params; // TBD: pass from outside - svector m_vars; - vector> m_monomials; + struct mon_eq { + mon_eq(lean::var_index v, svector const& vs): + m_v(v), m_vs(vs) {} + lean::var_index m_v; + svector m_vs; + }; + + vector m_monomials; unsigned_vector m_lim; + mutable std::unordered_map m_variable_values; // current model - imp(lean::lar_solver& s): s(s) { - m_lim.push_back(0); + imp(lean::lar_solver& s): + s(s) { } lean::final_check_status check_feasible() { @@ -24,21 +34,70 @@ namespace lp { } void add(lean::var_index v, unsigned sz, lean::var_index const* vs) { - m_vars.push_back(v); - m_monomials.push_back(svector(sz, vs)); + m_monomials.push_back(mon_eq(v, svector(sz, vs))); } void push() { - m_lim.push_back(m_vars.size()); + m_lim.push_back(m_monomials.size()); } void pop(unsigned n) { + if (n == 0) return; SASSERT(n < m_lim.size()); + m_monomials.shrink(m_lim[m_lim.size() - n]); m_lim.shrink(m_lim.size() - n); - m_vars.shrink(m_lim.back()); - m_monomials.shrink(m_lim.back()); } + /* + \brief Check if polynomials are well defined. + multiply values for vs and check if they are equal to value for v. + epsilon has been computed. + */ + bool check_assignment(mon_eq const& m) const { + rational r1 = m_variable_values[m.m_v]; + rational r2(1); + for (auto w : m.m_vs) { + r2 *= m_variable_values[w]; + } + return r1 == r2; + } + + bool check_assignments() const { + s.get_model(m_variable_values); + for (auto const& m : m_monomials) { + if (!check_assignment(m)) return false; + } + return true; + } + + + /** + \brief one-shot nlsat check. + A one shot checker is the least functionality that can + enable non-linear reasoning. + In addition to checking satisfiability we would also need + to identify equalities in the model that should be assumed + with the remaining solver. + + TBD: use partial model from lra_solver to prime the state of nlsat_solver. + */ + lbool check_nlsat() { + nlsat::solver solver(m_limit, m_params); + // add linear inequalities from lra_solver + // add polynomial definitions. + for (auto const& m : m_monomials) { + add_monomial_eq(solver, m); + } + lbool r = solver.check(); + if (r == l_true) { + // TBD extract model. + } + return r; + } + + void add_monomial_eq(nlsat::solver& solver, mon_eq const& m) { + + } }; nra_solver::nra_solver(lean::lar_solver& s) {