mirror of
https://github.com/Z3Prover/z3
synced 2026-05-27 12:26:25 +00:00
Nl2lin - integrate a linear under approximation of a CAD cell by Valentin Promies. (#8982)
* outline of signature for assignment based conflict generation Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * outline of interface contract Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * remove confusing construction Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * add material in nra-solver to interface Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * add marshaling from nlsat lemmas into core solver Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * tidy Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * add call to check-assignment Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * Nl2lin (#7795) * add linearized projection in nlsat * implement nlsat check for given assignment * add some comments * fixup loop Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * updates Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * fixes Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * debug nl2lin Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * Nl2lin (#7827) * fix linear projection * fix linear projection * use an explicit cell description in check_assignment * clean up (#7844) * Simplify no effect checks in nla_core.cpp Move up linear nlsat call to replace bounded nlsat. * t Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * t Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * detangle mess Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * remove the too early return Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * do not set use_nra_model to true Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * remove a comment Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * add a hook to add new multiplication definitions in nla_core * add internalization routine that uses macro-expanded polynomial representation Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * add internalization routine that uses macro-expanded polynomial representation Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * fixup backtranslation to not use roots Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * call setup_assignment_solver instead of setup_solver Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * debug the setup, still not working Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * updated clang format Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * simplify Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> * create polynomials with integer coefficients, use the hook to create new monomials Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * integrating changes from master related to work with polynomials Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * add forgotten files Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * Update nlsat_explain.cpp Remove a duplicate call * fix * move linear cell construction to levelwise * fix * fix * Port throttle and soundness fixes from master - Fix soundness: pop incomplete lemma from m_lemmas on add_lemma failure - Gracefully handle root atoms in add_lemma - Throttle check_assignment with failure counter (decrement on success) - Add arith.nl.nra_check_assignment parameter Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add arith.nl.nra_check_assignment_max_fail parameter Replace hardcoded failure threshold with configurable parameter (default 10). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add cha_abort_on_fail parameter to control failure counter decrement Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * abort nla check_assignment after a set number of allowed failures Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * Add missing AST query methods to Java API (#8977) * add Expr.isGround() to Java API Expose Z3_is_ground as a public method on Expr. Returns true when the expression contains no free variables. * add Expr.isLambda() to Java API Expose Z3_is_lambda as a public method on Expr. Returns true when the expression is a lambda quantifier. * add AST.getDepth() to Java API Expose Z3_get_depth as a public method on AST. Returns the maximum number of nodes on any path from root to leaf. * add ArraySort.getArity() to Java API Expose Z3_get_array_arity as a public method on ArraySort. Returns the number of dimensions of a multi-dimensional array sort. * add DatatypeSort.isRecursive() to Java API Expose Z3_is_recursive_datatype_sort as a public method on DatatypeSort. Returns true when the datatype refers to itself. * add FPExpr.isNumeral() to Java API Expose Z3_fpa_is_numeral as a public method on FPExpr. Returns true when the expression is a concrete floating-point value. * add isGroundExample test to JavaExample Test Expr.isGround() on constants, variables, and compound expressions. * add astDepthExample test to JavaExample Test AST.getDepth() on leaf nodes and nested expressions to verify the depth computation. * add arrayArityExample test to JavaExample Test ArraySort.getArity() on single-domain and multi-domain array sorts. * add recursiveDatatypeExample test to JavaExample Test DatatypeSort.isRecursive() on a recursive list datatype and a non-recursive pair datatype. * add fpNumeralExample test to JavaExample Test FPExpr.isNumeral() on a floating point constant and a symbolic variable. * add isLambdaExample test to JavaExample Test Expr.isLambda() on a lambda expression and a plain variable. * change the default number of failures in check_assignment to 7 Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * Fix high and medium priority API coherence issues (Go, Java, C++, TypeScript) (#8983) * Initial plan * Add missing API functions to Go, Java, C++, and TypeScript bindings Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * qf-s-benchmark: debug build + seq tracing + seq-fast/nseq-slow trace analysis (#8988) * Initial plan * Update qf-s-benchmark: debug build, seq tracing, trace analysis Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * disable linear approximation by default to check the merge Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * set check_assignment to true Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * fix restore_x by recalulating new column values Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * fix restore_x by recalulating new column values Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * fix a memory leak Signed-off-by: Lev Nachmanson <levnach@hotmail.com> --------- Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com> Signed-off-by: Lev Nachmanson <levnach@hotmail.com> Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com> Co-authored-by: ValentinPromies <44966217+ValentinPromies@users.noreply.github.com> Co-authored-by: Valentin Promies <valentin.promies@rwth-aachen.de> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Angelica Moreira <48168649+angelica-moreira@users.noreply.github.com> Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com>
This commit is contained in:
parent
cb13fa2325
commit
6fb68ac010
17 changed files with 497 additions and 22 deletions
|
|
@ -75,6 +75,8 @@ namespace nlsat {
|
|||
mutable std_vector<unsigned> m_deg_in_order_graph; // degree of polynomial in resultant graph
|
||||
mutable std_vector<unsigned> m_unique_neighbor; // UINT_MAX = not set, UINT_MAX-1 = multiple
|
||||
|
||||
bool m_linear_cell = false; // indicates whether cell bounds are forced to be linear
|
||||
|
||||
assignment const& sample() const { return m_solver.sample(); }
|
||||
|
||||
struct root_function {
|
||||
|
|
@ -231,7 +233,8 @@ namespace nlsat {
|
|||
assignment const&,
|
||||
pmanager& pm,
|
||||
anum_manager& am,
|
||||
polynomial::cache& cache)
|
||||
polynomial::cache& cache,
|
||||
bool linear)
|
||||
: m_solver(solver),
|
||||
m_P(ps),
|
||||
m_n(max_x),
|
||||
|
|
@ -240,7 +243,8 @@ namespace nlsat {
|
|||
m_cache(cache),
|
||||
m_todo(m_cache, true),
|
||||
m_level_ps(m_pm),
|
||||
m_psc_tmp(m_pm) {
|
||||
m_psc_tmp(m_pm),
|
||||
m_linear_cell(linear) {
|
||||
m_I.reserve(m_n);
|
||||
for (unsigned i = 0; i < m_n; ++i)
|
||||
m_I.emplace_back(m_pm);
|
||||
|
|
@ -1007,6 +1011,66 @@ namespace nlsat {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void add_linear_poly_from_root(anum const& a, bool lower, polynomial_ref& p) {
|
||||
rational r;
|
||||
m_am.to_rational(a, r);
|
||||
p = m_pm.mk_polynomial(m_level);
|
||||
p = denominator(r)*p - numerator(r);
|
||||
|
||||
if (lower) {
|
||||
m_I[m_level].l = p;
|
||||
m_I[m_level].l_index = 1;
|
||||
} else {
|
||||
m_I[m_level].u = p;
|
||||
m_I[m_level].u_index = 1;
|
||||
}
|
||||
m_level_ps.push_back(p);
|
||||
m_poly_has_roots.push_back(true);
|
||||
polynomial_ref w = choose_nonzero_coeff(p, m_level);
|
||||
m_witnesses.push_back(w);
|
||||
}
|
||||
|
||||
// Ensure that the interval bounds will be described by linear polynomials.
|
||||
// If this is not already the case, the working set of polynomials is extended by
|
||||
// new linear polynomials whose roots under-approximate the cell boundary.
|
||||
// Based on: Valentin Promies, Jasper Nalbach, Erika Abraham and Paul Wagner
|
||||
// "More is Less: Adding Polynomials for Faster Explanations in NLSAT" (CADE30, 2025)
|
||||
void add_linear_approximations(anum const& v) {
|
||||
polynomial_ref p_lower(m_pm), p_upper(m_pm);
|
||||
auto& r = m_rel.m_rfunc;
|
||||
if (m_I[m_level].is_section()) {
|
||||
if (!m_am.is_rational(v)) {
|
||||
NOT_IMPLEMENTED_YET();
|
||||
}
|
||||
else if (m_pm.total_degree(m_I[m_level].l) > 1) {
|
||||
add_linear_poly_from_root(v, true, p_lower);
|
||||
// update root function ordering
|
||||
r.emplace((r.begin() + m_l_rf), m_am, p_lower, 1, v, m_level_ps.size()-1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// sector: have to consider lower and upper bound
|
||||
if (!m_I[m_level].l_inf() && m_pm.total_degree(m_I[m_level].l) > 1) {
|
||||
scoped_anum between(m_am);
|
||||
m_am.select(r[m_l_rf].val, v, between);
|
||||
add_linear_poly_from_root(between, true, p_lower);
|
||||
// update root function ordering
|
||||
r.emplace((r.begin() + m_l_rf + 1), m_am, p_lower, 1, between, m_level_ps.size()-1);
|
||||
++m_l_rf;
|
||||
if (is_set(m_u_rf))
|
||||
++m_u_rf;
|
||||
}
|
||||
if (!m_I[m_level].u_inf() && m_pm.total_degree(m_I[m_level].u) > 1) {
|
||||
scoped_anum between(m_am);
|
||||
m_am.select(v, r[m_u_rf].val, between);
|
||||
// update root function ordering
|
||||
add_linear_poly_from_root(between, false, p_upper);
|
||||
r.emplace((r.begin() + m_u_rf), m_am, p_upper, 1, between, m_level_ps.size()-1);
|
||||
}
|
||||
}
|
||||
|
||||
// Build Θ (root functions) and pick I_level around sample(level).
|
||||
// Sets m_l_rf/m_u_rf and m_I[level].
|
||||
// Returns whether any roots were found (i.e., whether a relation can be built).
|
||||
|
|
@ -1022,6 +1086,10 @@ namespace nlsat {
|
|||
return false;
|
||||
|
||||
set_interval_from_root_partition(v, mid);
|
||||
|
||||
if (m_linear_cell)
|
||||
add_linear_approximations(v);
|
||||
|
||||
compute_side_mask();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1376,8 +1444,9 @@ namespace nlsat {
|
|||
assignment const& s,
|
||||
pmanager& pm,
|
||||
anum_manager& am,
|
||||
polynomial::cache& cache)
|
||||
: m_impl(new impl(solver, ps, n, s, pm, am, cache)) {}
|
||||
polynomial::cache& cache,
|
||||
bool linear)
|
||||
: m_impl(new impl(solver, ps, n, s, pm, am, cache, linear)) {}
|
||||
|
||||
levelwise::~levelwise() { delete m_impl; }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue