Skip to content

Commit 30f5599

Browse files
committed
use fixed vars to explain tightening
Signed-off-by: Lev Nachmanson <[email protected]>
1 parent 36293ac commit 30f5599

File tree

3 files changed

+55
-41
lines changed

3 files changed

+55
-41
lines changed

src/math/lp/dioph_eq.cpp

+45-39
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ namespace lp {
372372

373373
void subs_front_in_indexed_vector(std::queue<unsigned> & q) {
374374
unsigned k = pop_front(q);
375+
if (m_indexed_work_vector[k].is_zero()) return;
375376
const eprime_entry& e = entry_for_subs(k);
376377
TRACE("dioph_eq", tout << "k:" << k << ", in "; print_term_o(create_term_from_ind_c(), tout) << std::endl;
377378
tout << "subs with e:"; print_eprime_entry(e, tout) << std::endl;);
@@ -557,7 +558,15 @@ namespace lp {
557558
return false;
558559
}
559560
// g is not trivial, trying to tighten the bounds
560-
return tighten_bounds_for_term(g, j);
561+
// by using bitwise to explore both bounds
562+
return tighten_bounds_for_term(g, j, true) | tighten_bounds_for_term(g, j, false);
563+
}
564+
565+
void get_expl_from_meta_term(const lar_term& t, explanation& ex) {
566+
for (const auto& p: t) {
567+
const auto& l = lra.get_term(p.j());
568+
get_expl_from_lar_term(l, ex);
569+
}
561570
}
562571

563572
void get_expl_from_lar_term(const lar_term & l, explanation& ex) {
@@ -580,13 +589,13 @@ namespace lp {
580589
u_dependency *b_dep = nullptr;
581590
if (lra.has_upper_bound(j, b_dep, rs, is_strict)) {
582591
if (m_c > rs || (is_strict && m_c == rs)) {
583-
get_expl_from_lar_term(m_tmp_l, m_infeas_explanation);
592+
get_expl_from_meta_term(m_tmp_l, m_infeas_explanation);
584593
return;
585594
}
586595
}
587596
if (lra.has_lower_bound(j, b_dep, rs, is_strict)) {
588597
if (m_c < rs || (is_strict && m_c == rs)) {
589-
get_expl_from_lar_term(m_tmp_l, m_infeas_explanation);
598+
get_expl_from_meta_term(m_tmp_l, m_infeas_explanation);
590599
}
591600
}
592601
}
@@ -595,36 +604,25 @@ namespace lp {
595604
// m_indexed_work_vector contains the coefficients of the term
596605
// m_c contains the constant term
597606
// m_tmp_l is the linear combination of the equations that removs the substituted variablse
598-
bool tighten_bounds_for_term(const mpq& g, unsigned j) {
607+
bool tighten_bounds_for_term(const mpq& g, unsigned j, bool is_upper) {
599608
mpq rs;
600609
bool is_strict;
601-
bool change = false;
602610
u_dependency *b_dep = nullptr;
603611
SASSERT(!g.is_zero());
604612

605-
if (lra.has_upper_bound(j, b_dep, rs, is_strict)) {
613+
if (lra.has_bound_of_type(j, b_dep, rs, is_strict, is_upper)) {
606614
TRACE("dioph_eq", tout << "current upper bound for x:" << j << ":" << rs << std::endl;);
607615
rs = (rs - m_c) / g;
608616
TRACE("dioph_eq", tout << "(rs - m_c) / g:" << rs << std::endl;);
609617
if (!rs.is_int()) {
610-
tighten_bound_for_term_for_bound_kind(g, j, rs, true);
611-
change = true;
612-
}
613-
}
614-
if (lra.has_lower_bound(j, b_dep, rs, is_strict)) {
615-
TRACE("dioph_eq", tout << "current lower bound for x" << j << ":" << rs << std::endl;);
616-
rs = (rs - m_c) / g;
617-
TRACE("dioph_eq", tout << "(rs - m_c) / g:" << rs << std::endl;);
618-
if (!rs.is_int()) {
619-
tighten_bound_for_term_for_bound_kind(g, j, rs, false);
620-
change = true;
618+
tighten_bound_for_term_for_bound_kind(g, j, rs, is_upper, b_dep);
619+
return true;
621620
}
622621
}
623-
return change;
624-
622+
return false;
625623
}
626624

627-
void tighten_bound_for_term_for_bound_kind( const mpq& g, unsigned j, const mpq & ub, bool upper) {
625+
void tighten_bound_for_term_for_bound_kind( const mpq& g, unsigned j, const mpq & ub, bool upper, u_dependency* prev_dep) {
628626
// ub = (upper_bound(j) - m_c)/g.
629627
// we have x[j] = t = g*t_+ m_c <= upper_bound(j), then
630628
// t_ <= floor((upper_bound(j) - m_c)/g) = floor(ub)
@@ -638,42 +636,40 @@ namespace lp {
638636

639637
SASSERT(upper && bound < lra.get_upper_bound(j).x || !upper && bound > lra.get_lower_bound(j).x);
640638
lconstraint_kind kind = upper? lconstraint_kind::LE: lconstraint_kind::GE;
641-
u_dependency* dep = collect_explanation_from_indexed_vector(upper);
642-
dep = lra.mk_join(dep, explain_fixed(m_tmp_l));
639+
u_dependency* dep = prev_dep;
640+
dep = lra.mk_join(dep, explain_fixed_in_meta_term(m_tmp_l));
643641
u_dependency* j_bound_dep = upper? lra.get_column_upper_bound_witness(j): lra.get_column_lower_bound_witness(j);
644642
dep = lra.mk_join(dep, j_bound_dep);
645643
TRACE("dioph_eq", tout << "jterm:"; print_lar_term_L(lra.get_term(j), tout) << "\ndep:"; print_dep(tout, dep) << std::endl;);
646644
lra.update_column_type_and_bound(j, kind, bound, dep);
647645
}
648646

649-
u_dependency* explain_fixed(const lar_term& t) {
647+
u_dependency* explain_fixed_in_meta_term(const lar_term& t) {
650648
u_dependency* dep = nullptr;
649+
651650
for (const auto& p: t) {
652-
if (is_fixed(p.j())) {
653-
u_dependency* bound_dep = lra.get_bound_constraint_witnesses_for_column(p.j());
654-
dep = lra.mk_join(dep, bound_dep);
651+
lar_term const& term = lra.get_term(p.j());
652+
for (const auto& q: term) {
653+
if (is_fixed(q.j())) {
654+
u_dependency* bound_dep = lra.get_bound_constraint_witnesses_for_column(q.j());
655+
dep = lra.mk_join(dep, bound_dep);
656+
}
655657
}
656658
}
657659
return dep;
658660
}
659661

660-
u_dependency* collect_explanation_from_indexed_vector(bool upper) {
661-
TRACE("dioph_eq",
662-
tout << (upper?"upper":"lower") << std::endl;
663-
tout << "indexed_vec:"; print_term_o(create_term_from_ind_c(), tout);
664-
);
665-
666-
term_o t = remove_fresh_vars(create_term_from_ind_c());
667-
662+
u_dependency* explain_fixed(const lar_term& t) {
668663
u_dependency* dep = nullptr;
669-
int bound_sign = upper? 1: -1;
670664
for (const auto& p: t) {
671-
int var_bound_sign = p.coeff().is_pos()? bound_sign: -bound_sign;
672-
u_dependency* bound_dep = (var_bound_sign == 1? lra.get_column_upper_bound_witness(p.var()): lra.get_column_lower_bound_witness(p.var()));
673-
dep = lra.mk_join(dep, bound_dep);
665+
if (is_fixed(p.j())) {
666+
u_dependency* bound_dep = lra.get_bound_constraint_witnesses_for_column(p.j());
667+
dep = lra.mk_join(dep, bound_dep);
668+
}
674669
}
675670
return dep;
676671
}
672+
677673
public:
678674
lia_move check() {
679675
init();
@@ -916,7 +912,17 @@ namespace lp {
916912
out << "\tm_l:{"; print_lar_term_L(e.m_l, out) << "}, ";
917913
print_ml(e.m_l, out<< " \topened m_l:") << "\n";
918914
}
919-
out << "}\n";
915+
switch (e.m_entry_status)
916+
{
917+
case entry_status::F:
918+
out << "\tF\n";
919+
break;
920+
case entry_status::S:
921+
out << "\tS\n";
922+
break;
923+
default:
924+
out << "\tNOSF\n";
925+
}
920926
return out;
921927
}
922928

src/math/lp/lar_solver.cpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -1060,7 +1060,13 @@ namespace lp {
10601060
}
10611061
return ret;
10621062
}
1063-
1063+
bool lar_solver::has_bound_of_type(lpvar var, u_dependency*& ci, mpq& value, bool& is_strict, bool is_upper) const {
1064+
if (is_upper) {
1065+
return has_upper_bound(var, ci, value, is_strict);
1066+
} else {
1067+
return has_lower_bound(var, ci, value, is_strict);
1068+
}
1069+
}
10641070
bool lar_solver::has_lower_bound(lpvar var, u_dependency*& dep, mpq& value, bool& is_strict) const {
10651071

10661072
if (var >= m_columns.size()) {

src/math/lp/lar_solver.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ class lar_solver : public column_namer {
510510
u_dependency_manager& dep_manager() { return m_dependencies; }
511511

512512
inline u_dependency* get_column_upper_bound_witness(unsigned j) const {
513-
return m_columns[j].upper_bound_witness();
513+
return m_columns[j].upper_bound_witness();
514514
}
515515

516516
inline const impq& get_upper_bound(lpvar j) const {
@@ -527,6 +527,8 @@ class lar_solver : public column_namer {
527527

528528
bool has_lower_bound(lpvar var, u_dependency*& ci, mpq& value, bool& is_strict) const;
529529
bool has_upper_bound(lpvar var, u_dependency*& ci, mpq& value, bool& is_strict) const;
530+
bool has_bound_of_type(lpvar var, u_dependency*& ci, mpq& value, bool& is_strict, bool is_upper) const;
531+
530532
bool has_value(lpvar var, mpq& value) const;
531533
bool fetch_normalized_term_column(const lar_term& t, std::pair<mpq, lpvar>&) const;
532534
bool column_is_fixed(unsigned j) const;

0 commit comments

Comments
 (0)