3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-12-31 08:19:54 +00:00
z3/src/nlsat/nlsat_common.cpp
Lev Nachmanson bf32a437c1 canonicalize polinomals in todo_set
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
2025-12-08 11:33:31 -10:00

104 lines
2.7 KiB
C++

/*++
Copyright (c) 2012 Microsoft Corporation
Module Name:
nlsat_common.cpp
Abstract:
some common routines from nlsat
Author:
Lev Nachmanson(levnach@hotmail.com) 2025-October.
Revision History:
--*/
#include "nlsat/nlsat_common.h"
namespace nlsat {
todo_set::todo_set(polynomial::cache& u, bool canonicalize): m_cache(u), m_set(u.pm()), m_canonicalize(canonicalize) {}
void todo_set::reset() {
pmanager& pm = m_set.m();
unsigned sz = m_set.size();
for (unsigned i = 0; i < sz; i++) {
m_in_set[pm.id(m_set.get(i))] = false;
}
m_set.reset();
}
void todo_set::insert(poly* p) {
pmanager& pm = m_set.m();
if (m_canonicalize) {
// Canonicalize content+sign so scalar multiples share the same representative.
if (!pm.is_zero(p) && !pm.is_const(p)) {
polynomial_ref prim(pm);
var x = pm.max_var(p);
pm.primitive(p, x, prim);
p = prim.get();
}
p = pm.flip_sign_if_lm_neg(p);
}
p = m_cache.mk_unique(p);
unsigned pid = pm.id(p);
if (m_in_set.get(pid, false))
return;
m_in_set.setx(pid, true, false);
m_set.push_back(p);
}
bool todo_set::empty() const { return m_set.empty(); }
// Return max variable in todo_set
var todo_set::max_var() const {
pmanager& pm = m_set.m();
var max = null_var;
unsigned sz = m_set.size();
for (unsigned i = 0; i < sz; i++) {
var x = pm.max_var(m_set.get(i));
SASSERT(x != null_var);
if (max == null_var || x > max)
max = x;
}
return max;
}
/**
\brief Remove the maximal polynomials from the set and store
them in max_polys. Return the maximal variable
*/
var todo_set::extract_max_polys(polynomial_ref_vector& max_polys) {
max_polys.reset();
var x = max_var();
pmanager& pm = m_set.m();
unsigned sz = m_set.size();
unsigned j = 0;
for (unsigned i = 0; i < sz; i++) {
poly* p = m_set.get(i);
var y = pm.max_var(p);
SASSERT(y <= x);
if (y == x) {
max_polys.push_back(p);
m_in_set[pm.id(p)] = false;
}
else {
m_set.set(j, p);
j++;
}
}
m_set.shrink(j);
return x;
}
/**
\brief Wrapper for factorization
*/
void factor(polynomial_ref & p, polynomial::cache& cache, polynomial_ref_vector & fs) {
TRACE(nlsat_factor, tout << "factor\n" << p << "\n";);
fs.reset();
cache.factor(p.get(), fs);
}
}