mirror of
https://github.com/Z3Prover/z3
synced 2025-10-27 01:39:22 +00:00
create a better queue on properties
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
b09199c6e6
commit
b85cba762c
1 changed files with 62 additions and 23 deletions
|
|
@ -73,19 +73,63 @@ namespace nlsat {
|
||||||
};
|
};
|
||||||
typedef std::priority_queue<property, std::vector<property>, compare_prop_tags> property_queue;
|
typedef std::priority_queue<property, std::vector<property>, compare_prop_tags> property_queue;
|
||||||
|
|
||||||
std::vector<property> to_vector(property_queue& pq) {
|
// p_q_plus: Enhanced property queue that allows iteration without modification
|
||||||
std::vector<property> result;
|
class p_q_plus {
|
||||||
while (!pq.empty()) {
|
private:
|
||||||
result.push_back(pq.top());
|
property_queue m_queue;
|
||||||
pq.pop();
|
std::vector<property> m_elements; // Maintains all enqueued elements for iteration
|
||||||
|
|
||||||
|
public:
|
||||||
|
p_q_plus() = default;
|
||||||
|
|
||||||
|
// Push a property to the queue and maintain the elements vector
|
||||||
|
void push(const property& p) {
|
||||||
|
m_queue.push(p);
|
||||||
|
m_elements.push_back(p);
|
||||||
}
|
}
|
||||||
// Restore the queue
|
|
||||||
for (const auto& item : result) {
|
size_t size() const { return m_queue.size(); }
|
||||||
pq.push(item);
|
|
||||||
|
// Pop and return the top element
|
||||||
|
property pop() {
|
||||||
|
property p = m_queue.top();
|
||||||
|
m_queue.pop();
|
||||||
|
// Remove from elements vector
|
||||||
|
auto it = std::find_if(m_elements.begin(), m_elements.end(),
|
||||||
|
[&p](const property& elem) {
|
||||||
|
return elem.m_prop_tag == p.m_prop_tag &&
|
||||||
|
elem.m_poly == p.m_poly &&
|
||||||
|
elem.m_root_index == p.m_root_index;
|
||||||
|
});
|
||||||
|
if (it != m_elements.end()) {
|
||||||
|
m_elements.erase(it);
|
||||||
|
}
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
// Check if queue is empty
|
||||||
|
bool empty() const {
|
||||||
|
return m_queue.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get reference to underlying elements for iteration
|
||||||
|
const std::vector<property>& elements() const {
|
||||||
|
return m_elements;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterator interface
|
||||||
|
auto begin() const { return m_elements.begin(); }
|
||||||
|
auto end() const { return m_elements.end(); }
|
||||||
|
|
||||||
|
// Clear the queue and elements
|
||||||
|
void clear() {
|
||||||
|
while (!m_queue.empty()) {
|
||||||
|
m_queue.pop();
|
||||||
|
}
|
||||||
|
m_elements.clear();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct root_function {
|
struct root_function {
|
||||||
scoped_anum val;
|
scoped_anum val;
|
||||||
indexed_root_expr ire;
|
indexed_root_expr ire;
|
||||||
|
|
@ -103,7 +147,7 @@ namespace nlsat {
|
||||||
unsigned m_level;// the current level while refining the properties
|
unsigned m_level;// the current level while refining the properties
|
||||||
pmanager& m_pm;
|
pmanager& m_pm;
|
||||||
anum_manager& m_am;
|
anum_manager& m_am;
|
||||||
std::vector<property_queue> m_Q; // the set of properties to prove
|
std::vector<p_q_plus> m_Q; // the set of properties to prove
|
||||||
std::vector<property> m_to_refine;
|
std::vector<property> m_to_refine;
|
||||||
std::vector<root_function_interval> m_I; // intervals per level (indexed by variable/level)
|
std::vector<root_function_interval> m_I; // intervals per level (indexed by variable/level)
|
||||||
bool m_fail = false;
|
bool m_fail = false;
|
||||||
|
|
@ -159,10 +203,8 @@ namespace nlsat {
|
||||||
unsigned level = 0;
|
unsigned level = 0;
|
||||||
for (auto &q: m_Q) {
|
for (auto &q: m_Q) {
|
||||||
if (q.empty()) { level++; continue; }
|
if (q.empty()) { level++; continue; }
|
||||||
auto q_dump = to_vector(q);
|
|
||||||
|
|
||||||
out << "level:" << level << "[\n";
|
out << "level:" << level << "[\n";
|
||||||
for (const auto& pr : q_dump) {
|
for (const auto& pr : q) {
|
||||||
display(out, pr) << "\n";
|
display(out, pr) << "\n";
|
||||||
}
|
}
|
||||||
out << "]\n";
|
out << "]\n";
|
||||||
|
|
@ -351,10 +393,8 @@ namespace nlsat {
|
||||||
TRACE(lws, display_relation(tout) << std::endl;);
|
TRACE(lws, display_relation(tout) << std::endl;);
|
||||||
}
|
}
|
||||||
|
|
||||||
property pop(property_queue & q) {
|
property pop(p_q_plus& q) {
|
||||||
property r = q.top();
|
return q.pop();
|
||||||
q.pop();
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//works on m_level
|
//works on m_level
|
||||||
|
|
@ -379,7 +419,7 @@ namespace nlsat {
|
||||||
void build_representation() {
|
void build_representation() {
|
||||||
// collect non-null polynomials (up to polynomial_manager equality)
|
// collect non-null polynomials (up to polynomial_manager equality)
|
||||||
std::vector<const poly*> p_non_null;
|
std::vector<const poly*> p_non_null;
|
||||||
for (auto & pr: to_vector(m_Q[m_level])) {
|
for (auto & pr: m_Q[m_level]) {
|
||||||
if (!pr.m_poly) continue;
|
if (!pr.m_poly) continue;
|
||||||
SASSERT(max_var(pr.m_poly) == m_level);
|
SASSERT(max_var(pr.m_poly) == m_level);
|
||||||
if (pr.m_prop_tag == prop_enum::sgn_inv
|
if (pr.m_prop_tag == prop_enum::sgn_inv
|
||||||
|
|
@ -476,7 +516,7 @@ namespace nlsat {
|
||||||
// Equivalence: same m_prop_tag and same level; require the same poly as well.
|
// Equivalence: same m_prop_tag and same level; require the same poly as well.
|
||||||
void add_to_Q_if_new(const property & pr, unsigned level) {
|
void add_to_Q_if_new(const property & pr, unsigned level) {
|
||||||
SASSERT(pr.m_prop_tag != ord_inv || (pr.m_poly && !m_pm.is_zero(pr.m_poly)));
|
SASSERT(pr.m_prop_tag != ord_inv || (pr.m_poly && !m_pm.is_zero(pr.m_poly)));
|
||||||
for (auto const & q : to_vector(m_Q[level])) {
|
for (auto const & q : m_Q[level]) {
|
||||||
if (q.m_prop_tag != pr.m_prop_tag) continue;
|
if (q.m_prop_tag != pr.m_prop_tag) continue;
|
||||||
if (q.m_poly != pr.m_poly) continue;
|
if (q.m_poly != pr.m_poly) continue;
|
||||||
if (q.m_root_index != pr.m_root_index) continue;
|
if (q.m_root_index != pr.m_root_index) continue;
|
||||||
|
|
@ -933,8 +973,7 @@ or
|
||||||
|
|
||||||
bool invariant() {
|
bool invariant() {
|
||||||
for (unsigned i = 0; i < m_Q.size(); i++) {
|
for (unsigned i = 0; i < m_Q.size(); i++) {
|
||||||
auto qv = to_vector(m_Q[i]);
|
bool level_is_ok = std::all_of(m_Q[i].begin(), m_Q[i].end(), [this, i](const property& p){
|
||||||
bool level_is_ok = std::all_of(qv.begin(), qv.end(), [this, i](const property& p){
|
|
||||||
|
|
||||||
bool r = !(p.m_poly) || (max_var(p.m_poly) == i);
|
bool r = !(p.m_poly) || (max_var(p.m_poly) == i);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue