3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-22 16:45:31 +00:00

Remove m_final from spanning tree representation

This commit is contained in:
Anh-Dung Phan 2013-11-06 13:30:29 -08:00
parent cf75a7743e
commit 034b33b6da
5 changed files with 55 additions and 74 deletions

View file

@ -23,6 +23,7 @@ Notes:
#include"smt_context.h"
#include"theory_arith.h"
#include"theory_diff_logic.h"
#include "ast_pp.h"
namespace opt {
@ -94,7 +95,13 @@ namespace opt {
lbool opt_solver::check_sat_core(unsigned num_assumptions, expr * const * assumptions) {
TRACE("opt_solver_na2as", tout << "opt_opt_solver::check_sat_core: " << num_assumptions << "\n";);
TRACE("opt_solver_na2as", {
tout << "opt_opt_solver::check_sat_core: " << m_context.size() << "\n";
for (unsigned i = 0; i < m_context.size(); ++i) {
tout << mk_pp(m_context.get_formulas()[i], m_context.m()) << "\n";
}
});
lbool r = m_context.check(num_assumptions, assumptions);
if (r == l_true && m_objective_enabled) {
m_objective_values.reset();

View file

@ -115,7 +115,7 @@ namespace opt {
verbose_stream() << m_lower[i] << " ";
}
verbose_stream() << "\n";
// model_pp(verbose_stream(), *md);
model_pp(verbose_stream(), *md);
);
expr_ref_vector disj(m);
expr_ref constraint(m);

View file

@ -127,6 +127,7 @@ namespace smt {
bool check_well_formed();
bool is_preorder_traversal(node start, node end);
node get_final(int start);
public:

View file

@ -69,7 +69,6 @@ namespace smt {
m_pred.resize(num_nodes);
m_depth.resize(num_nodes);
m_thread.resize(num_nodes);
m_final.resize(num_nodes);
m_step = 0;
}
@ -84,7 +83,6 @@ namespace smt {
m_pred[root] = -1;
m_depth[root] = 0;
m_thread[root] = 0;
m_final[root] = root - 1;
m_potentials[root] = numeral::zero();
m_graph.init_var(root);
@ -106,7 +104,6 @@ namespace smt {
m_pred[i] = root;
m_depth[i] = 1;
m_thread[i] = i + 1;
m_final[i] = i;
m_states[num_edges + i] = BASIS;
node src = m_upwards[i] ? i : root;
node tgt = m_upwards[i] ? root : i;
@ -125,7 +122,6 @@ namespace smt {
TRACE("network_flow", {
tout << pp_vector("Predecessors", m_pred, true) << pp_vector("Threads", m_thread);
tout << pp_vector("Last Successors", m_final);
tout << pp_vector("Depths", m_depth) << pp_vector("Upwards", m_upwards);
tout << pp_vector("Potentials", m_potentials) << pp_vector("Flows", m_flows);
});
@ -148,7 +144,7 @@ namespace smt {
node tgt = m_graph.get_target(m_entering_edge);
numeral cost = m_graph.get_weight(m_entering_edge);
numeral change = m_upwards[src] ? (-cost - m_potentials[src] + m_potentials[tgt]) : (cost + m_potentials[src] - m_potentials[tgt]);
node last = m_thread[m_final[src]];
node last = m_thread[get_final(src)];
for (node u = src; u != last; u = m_thread[u]) {
m_potentials[u] += change;
}
@ -261,7 +257,6 @@ namespace smt {
template<typename Ext>
bool network_flow<Ext>::is_ancestor_of(node ancestor, node child) const {
for (node n = child; n != -1; n = m_pred[n]) {
// q should be in T_v so swap p and q
if (n == ancestor) {
return true;
}
@ -295,26 +290,15 @@ namespace smt {
Old tree: New tree:
root root
/ \ / \
x y
/ \ / \
u w'
| /
v w
/ \ \
z p
\
q
x y
/ \ / \
u w'
/
v w
/ \ \
z p
\ /
q
x y x y
/ \ / \ / \ / \
u s u s
| / /
v w v w
/ \ \ / \ \
z p z p
\ \ /
q q
*/
template<typename Ext>
@ -359,35 +343,39 @@ namespace smt {
n = next;
SASSERT(n != -1);
}
#else
node old_pred = m_pred[q];
#else
node old_pred = m_pred[q];
if (q != v) {
for (node n = q; n != u; ) {
SASSERT(old_pred != u || n == v); // the last processed node is v
TRACE("network_flow", {
tout << pp_vector("Predecessors", m_pred, true);
});
SASSERT(-1 != m_pred[old_pred]);
node next_old_pred = m_pred[old_pred];
swap_order(n, old_pred);
std::swap(m_upwards[n], prev_upwards);
prev_upwards = !prev_upwards; // flip previous version of upwards.
n = old_pred;
old_pred = next_old_pred;
}
}
m_pred[q] = p;
for (node n = q; n != u; ) {
SASSERT(old_pred != u || n == v); // the last processed node is v
SASSERT(-1 != m_pred[old_pred]);
node next_old_pred = m_pred[old_pred];
swap_order(n, old_pred);
std::swap(m_upwards[n], prev_upwards);
prev_upwards = !prev_upwards; // flip previous version of upwards.
n = old_pred;
old_pred = next_old_pred;
}
#endif
// m_thread and m_final were updated.
// m_thread were updated.
// update the depth.
fix_depth(q, m_final[q]);
fix_depth(q, get_final(q));
TRACE("network_flow", {
tout << pp_vector("Threads", m_thread, true);
tout << pp_vector("Predecessors", m_pred, true) << pp_vector("Threads", m_thread);
tout << pp_vector("Depths", m_depth) << pp_vector("Upwards", m_upwards);
});
}
/**
swap v and q in tree.
- fixup m_final
- fixup m_thread
- fixup m_pred
@ -407,31 +395,27 @@ namespace smt {
void network_flow<Ext>::swap_order(node q, node v) {
SASSERT(q != v);
SASSERT(m_pred[q] == v);
SASSERT(is_preorder_traversal(v, m_final[v]));
SASSERT(is_preorder_traversal(v, get_final(v)));
node prev = find_rev_thread(v);
node final_q = m_final[q];
node final_v = m_final[v];
node final_q = get_final(q);
node final_v = get_final(v);
node next = m_thread[final_v];
node alpha = find_rev_thread(q);
if (final_q == final_v) {
m_thread[final_q] = v;
m_thread[alpha] = next;
m_final[q] = alpha;
m_final[v] = alpha;
}
else {
node beta = m_thread[final_q];
node beta = m_thread[final_q];
m_thread[final_q] = v;
m_thread[alpha] = beta;
m_final[q] = final_v;
}
m_thread[prev] = q;
m_pred[v] = q;
SASSERT(is_preorder_traversal(q, m_final[q]));
SASSERT(is_preorder_traversal(q, get_final(q)));
}
template<typename Ext>
std::string network_flow<Ext>::display_spanning_tree() {
++m_step;;
@ -537,11 +521,11 @@ namespace smt {
roots[y] = x;
}
static int get_final(int start, svector<int> const & thread, svector<int> const & depth) {
// really final or should one take into account connected tree?
template<typename Ext>
dl_var network_flow<Ext>::get_final(int start) {
int n = start;
while (depth[thread[n]] > depth[start]) {
n = thread[n];
while (m_depth[m_thread[n]] > m_depth[start]) {
n = m_thread[n];
}
return n;
}
@ -566,7 +550,6 @@ namespace smt {
svector<node> m_pred; node |-> node
svector<int> m_depth; node |-> int
svector<node> m_thread; node |-> node
svector<node> m_final; node |-> node
Tree is determined by m_pred:
- m_pred[root] == -1
@ -577,9 +560,6 @@ namespace smt {
Furthermore, the nodes linked in m_thread follows a
depth-first traversal order.
m_final[n] is the last node in depth-first traversal order,
starting from n, that is still a child of n.
m_upwards direction of edge from i to m_pred[i] m_graph
*/
@ -593,6 +573,7 @@ namespace smt {
svector<bool> found(m_thread.size(), false);
found[root] = true;
for (node x = m_thread[root]; x != root; x = m_thread[x]) {
SASSERT(x != m_thread[x]);
found[x] = true;
}
for (unsigned i = 0; i < found.size(); ++i) {
@ -619,11 +600,6 @@ namespace smt {
SASSERT(m_depth[x] == m_depth[m_pred[x]] + 1);
}
// m_final of a node denotes the last node with a bigger depth
for (unsigned i = 0; i < m_final.size(); ++i) {
SASSERT(m_final[i] == get_final(i, m_thread, m_depth));
}
// m_thread forms a spanning tree over [0..root]
// Union-find structure
svector<int> roots(m_pred.size(), -1);
@ -635,11 +611,6 @@ namespace smt {
merge(roots, x, y);
}
std::cout << "roots" << std::endl;
for (unsigned i = 0; i < roots.size(); ++i) {
std::cout << i << " |-> " << roots[i] << std::endl;
}
// All nodes belong to the same spanning tree
for (unsigned i = 0; i < roots.size(); ++i) {
SASSERT(roots[i] + roots.size() == 0 || roots[i] >= 0);

View file

@ -50,8 +50,8 @@ class blast_term_ite_tactic : public tactic {
bool max_steps_exceeded(unsigned num_steps) const {
cooperate("blast term ite");
if (memory::get_allocation_size() > m_max_memory)
throw tactic_exception(TACTIC_MAX_MEMORY_MSG);
// if (memory::get_allocation_size() > m_max_memory)
// throw tactic_exception(TACTIC_MAX_MEMORY_MSG);
return false;
}
@ -62,6 +62,8 @@ class blast_term_ite_tactic : public tactic {
for (unsigned i = 0; i < num_args; ++i) {
expr* c, *t, *e;
if (!m.is_bool(args[i]) && m.is_ite(args[i], c, t, e)) {
enable_trace("blast_term_ite");
TRACE("blast_term_ite", result = m.mk_app(f, num_args, args); tout << result << "\n";);
expr_ref e1(m), e2(m);
ptr_vector<expr> args1(num_args, args);
args1[i] = t;