Skip to content

Commit 862dc91

Browse files
committed
work on incremental dio
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
1 parent fd3bd08 commit 862dc91

File tree

7 files changed

+189
-52
lines changed

7 files changed

+189
-52
lines changed

src/math/lp/dioph_eq.cpp

+99-38
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ namespace lp {
125125
m_c += t.c();
126126
return *this;
127127
}
128-
};
128+
};
129129

130130
std::ostream& print_S(std::ostream& out) {
131131
out << "S:\n";
@@ -204,7 +204,7 @@ namespace lp {
204204
NO_S_NO_F
205205
};
206206
struct entry {
207-
lar_term m_l;
207+
//lar_term m_l; the term is taken from matrix m_l_matrix of the index entry
208208
mpq m_c; // the constant of the term, the term is taken from the row of
209209
// m_e_matrix with the same index as the entry
210210
entry_status m_entry_status;
@@ -214,6 +214,7 @@ namespace lp {
214214
std_vector<entry> m_entries;
215215
// the terms are stored in m_A and m_c
216216
static_matrix<mpq, mpq> m_e_matrix; // the rows of the matrix are the terms,
217+
static_matrix<mpq, mpq> m_l_matrix; // the rows of the matrix are the l_terms : providing the certificate to the entries
217218
// without the constant part
218219
int_solver& lia;
219220
lar_solver& lra;
@@ -234,12 +235,12 @@ namespace lp {
234235
// {coeff*lar.get_term(k)})
235236

236237
std_vector<unsigned> m_k2s;
237-
std_vector<unsigned> m_fresh_definitions; // seems only needed in the debug
238-
// version in remove_fresh_vars
238+
std_vector<unsigned> m_fresh_definitions;
239239

240240
unsigned m_conflict_index = -1; // m_entries[m_conflict_index] gives the conflict
241241
unsigned m_max_number_of_iterations = 100;
242242
unsigned m_number_of_iterations;
243+
std_vector<std::unordered_set<unsigned>> m_columns_to_entries; // m_columnn_to_terms[j] is the set of of all k such that m_entry[k].m_l depends on j
243244
struct branch {
244245
unsigned m_j = UINT_MAX;
245246
mpq m_rs;
@@ -277,12 +278,57 @@ namespace lp {
277278
}
278279
};
279280

281+
struct undo_add_term : public trail {
282+
imp& m_s;
283+
lar_term m_t;
284+
undo_add_term(imp& s, const lar_term &t): m_s(s), m_t(t) {
285+
286+
}
287+
void undo () {
288+
NOT_IMPLEMENTED_YET();
289+
}
290+
};
291+
292+
293+
struct undo_add_column_bound : public trail {
294+
imp& m_s;
295+
unsigned m_j; // the column that has been added
296+
undo_add_column_bound(imp& s, unsigned j) : m_s(s), m_j(j) {}
297+
298+
void undo() override {
299+
NOT_IMPLEMENTED_YET();
300+
}
301+
};
302+
303+
std_vector<const lar_term*> m_added_terms;
304+
280305
std_vector<variable_branch_stats> m_branch_stats;
281306
std_vector<branch> m_branch_stack;
282307
std_vector<constraint_index> m_explanation_of_branches;
308+
void add_term_delegate(const lar_term* t) {
309+
unsigned j = t->j();
310+
if (!lra.column_is_int(j) || !lra.column_has_term(j))
311+
return;
312+
if (!all_vars_are_int(*t)) {
313+
TRACE("dioph_eq", tout << "not all vars are integrall\n";);
314+
return;
315+
}
316+
m_added_terms.push_back(t);
317+
auto undo = undo_add_term(*this, *t);
318+
lra.trail().push(undo);
319+
}
320+
321+
void add_column_bound_delegate(unsigned j) {
322+
if (!lra.column_is_int(j))
323+
return;
324+
auto undo = undo_add_column_bound(*this, j);
325+
lra.trail().push(undo) ;
326+
}
283327

284328
public:
285-
imp(int_solver& lia, lar_solver& lra) : lia(lia), lra(lra) {}
329+
imp(int_solver& lia, lar_solver& lra) : lia(lia), lra(lra) {
330+
lra.register_add_term_delegate([this](const lar_term*t){add_term_delegate(t);});
331+
}
286332
term_o get_term_from_entry(unsigned i) const {
287333
term_o t;
288334
for (const auto& p : m_e_matrix.m_rows[i]) {
@@ -304,11 +350,16 @@ namespace lp {
304350
// the term has form sum(a_i*x_i) - t.j() = 0,
305351
void fill_entry(const lar_term& t) {
306352
TRACE("dioph_eq", print_lar_term_L(t, tout) << std::endl;);
307-
entry te = {lar_term(t.j()), mpq(0), entry_status::F};
353+
entry te = { mpq(0), entry_status::F};
308354
unsigned entry_index = (unsigned) m_entries.size();
309355
m_f.push_back(entry_index);
310356
m_entries.push_back(te);
311357
entry& e = m_entries.back();
358+
SASSERT(m_l_matrix.row_count() == m_e_matrix.row_count());
359+
// fill m_l_matrix row
360+
m_l_matrix.add_row();
361+
m_l_matrix.add_new_element(entry_index, t.j(), mpq(1));
362+
// fill E-entry
312363
m_e_matrix.add_row();
313364
SASSERT(m_e_matrix.row_count() == m_entries.size());
314365

@@ -356,6 +407,11 @@ namespace lp {
356407
m_number_of_iterations = 0;
357408
m_branch_stack.clear();
358409
m_lra_level = 0;
410+
for (const lar_term* t: m_added_terms) {
411+
fill_entry(*t);
412+
}
413+
m_added_terms.clear();
414+
/*
359415
for (unsigned j = 0; j < lra.column_count(); j++) {
360416
if (!lra.column_is_int(j) || !lra.column_has_term(j))
361417
continue;
@@ -365,7 +421,7 @@ namespace lp {
365421
continue;
366422
}
367423
fill_entry(t);
368-
}
424+
}*/
369425
}
370426

371427
template <typename K>
@@ -437,7 +493,11 @@ namespace lp {
437493
p.coeff() /= g;
438494
}
439495
m_entries[ei].m_c = c_g;
440-
e.m_l *= (1 / g);
496+
// e.m_l *= (1 / g);
497+
for (auto& p : m_l_matrix.m_rows[ei]) {
498+
p.coeff() /= g;
499+
}
500+
441501
TRACE("dioph_eq", tout << "ep_m_e:";
442502
print_entry(ei, tout) << std::endl;);
443503
SASSERT(entry_invariant(ei));
@@ -511,13 +571,22 @@ namespace lp {
511571
q.push(j);
512572
}
513573
m_c += coeff * e.m_c;
514-
m_tmp_l += coeff * e.m_l;
574+
575+
m_tmp_l += coeff * l_term_from_row(k); // improve later
515576
TRACE("dioph_eq", tout << "after subs k:" << k << "\n";
516577
print_term_o(create_term_from_ind_c(), tout) << std::endl;
517578
tout << "m_tmp_l:{"; print_lar_term_L(m_tmp_l, tout);
518579
tout << "}, opened:"; print_ml(m_tmp_l, tout) << std::endl;);
519580
}
520581

582+
lar_term l_term_from_row(unsigned k) const {
583+
lar_term ret;
584+
for (const auto & p: m_l_matrix.m_rows[k])
585+
ret.add_monomial(p.coeff(), p.var());
586+
587+
return ret;
588+
}
589+
521590
term_o create_term_from_l(const lar_term& l) {
522591
term_o ret;
523592
for (const auto& p : l) {
@@ -718,8 +787,8 @@ namespace lp {
718787
// returns true only on a conflict.
719788
// m_indexed_work_vector contains the coefficients of the term
720789
// m_c contains the constant term
721-
// m_tmp_l is the linear combination of the equations that removs the
722-
// substituted variablse returns true iff the conflict is found
790+
// m_tmp_l is the linear combination of the equations that removes the
791+
// substituted variables, returns true iff the conflict is found
723792
bool tighten_bounds_for_non_trivial_gcd(const mpq& g, unsigned j,
724793
bool is_upper) {
725794
mpq rs;
@@ -781,7 +850,7 @@ namespace lp {
781850
return true;
782851
}
783852

784-
u_dependency* explain_fixed_in_meta_term(const lar_term& t) {
853+
template <typename T> u_dependency* explain_fixed_in_meta_term (const T& t) {
785854
return explain_fixed(open_ml(t));
786855
}
787856

@@ -831,16 +900,6 @@ namespace lp {
831900
return lia_move::undef;
832901
}
833902

834-
struct undo_fixed : public trail {
835-
lar_solver& m_lra;
836-
unsigned m_j; // the variable that became fixed
837-
undo_fixed(lar_solver& lra, unsigned j) : m_lra(lra), m_j(j) {}
838-
839-
void undo() override {
840-
NOT_IMPLEMENTED_YET();
841-
}
842-
};
843-
844903
void collect_evidence() {
845904
lra.get_infeasibility_explanation(m_infeas_explanation);
846905
for (const auto& p : m_infeas_explanation) {
@@ -894,7 +953,7 @@ namespace lp {
894953
tout << "fixed j:" << j <<", was substited by "; print_entry(m_k2s[j], tout););
895954
if (check_fixing(j) == lia_move::conflict) {
896955
auto& ep = m_entries[m_k2s[j]];
897-
for (auto ci : lra.flatten(explain_fixed_in_meta_term(ep.m_l))) {
956+
for (auto ci : lra.flatten(explain_fixed_in_meta_term(m_l_matrix.m_rows[m_k2s[j]]))) {
898957
m_explanation_of_branches.push_back(ci);
899958
}
900959
return lia_move::conflict;
@@ -929,11 +988,11 @@ namespace lp {
929988
}
930989
TRACE("dio_br", lra.print_column_info(b.m_j, tout) <<"add bound" << std::endl;);
931990
if (lra.column_is_fixed(b.m_j)) {
932-
unsigned local_mj;
933-
if (! m_var_register.external_is_used(b.m_j, local_mj))
991+
unsigned local_bj;
992+
if (! m_var_register.external_is_used(b.m_j, local_bj))
934993
return lia_move::undef;
935994

936-
if (fix_var(lar_solver_to_local(b.m_j)) == lia_move::conflict) {
995+
if (fix_var(local_bj) == lia_move::conflict) {
937996
TRACE("dio_br", tout << "conflict in fix_var" << std::endl;) ;
938997
return lia_move::conflict;
939998
}
@@ -1197,14 +1256,15 @@ namespace lp {
11971256
print_entry(i, tout) << std::endl;);
11981257
m_entries[i].m_c -= j_sign * coeff * e.m_c;
11991258
m_e_matrix.pivot_row_to_row_given_cell_with_sign(ei, c, j, j_sign);
1200-
m_entries[i].m_l -= j_sign * coeff * e.m_l;
1259+
//m_entries[i].m_l -= j_sign * coeff * e.m_l;
1260+
m_l_matrix.add_rows( -j_sign*coeff, ei, i);
12011261
TRACE("dioph_eq", tout << "after pivoting c_row:";
12021262
print_entry(i, tout););
12031263
CTRACE(
12041264
"dioph_eq", !entry_invariant(i), tout << "invariant delta:"; {
12051265
const auto& e = m_entries[i];
12061266
print_term_o(get_term_from_entry(ei) -
1207-
fix_vars(open_ml(e.m_l)),
1267+
fix_vars(open_ml(m_l_matrix.m_rows[ei])),
12081268
tout)
12091269
<< std::endl;
12101270
});
@@ -1226,19 +1286,20 @@ namespace lp {
12261286
const auto& e = m_entries[ei];
12271287
bool ret =
12281288
term_to_lar_solver(remove_fresh_vars(get_term_from_entry(ei))) ==
1229-
fix_vars(open_ml(e.m_l));
1289+
fix_vars(open_ml(m_l_matrix.m_rows[ei]));
12301290
if (ret)
12311291
return true;
12321292
TRACE("dioph_eq", tout << "get_term_from_entry(" << ei << "):";
12331293
print_term_o(get_term_from_entry(ei), tout) << std::endl;
12341294
tout << "remove_fresh_vars:";
12351295
print_term_o(remove_fresh_vars(get_term_from_entry(ei)), tout)
12361296
<< std::endl;
1237-
tout << "e.m_l:"; print_lar_term_L(e.m_l, tout) << std::endl;
1297+
tout << "e.m_l:"; print_lar_term_L(l_term_from_row(ei), tout) << std::endl;
12381298
tout << "open_ml(e.m_l):";
1239-
print_term_o(open_ml(e.m_l), tout) << std::endl;
1299+
print_term_o(open_ml(l_term_from_row(ei)), tout) << std::endl;
12401300
tout << "fix_vars(open_ml(e.m_l)):";
1241-
print_term_o(fix_vars(open_ml(e.m_l)), tout) << std::endl;);
1301+
print_term_o(fix_vars(open_ml(l_term_from_row(ei))), tout) << std::endl;
1302+
);
12421303
return false;
12431304
}
12441305

@@ -1276,7 +1337,7 @@ namespace lp {
12761337
return print_term_o(opened_ml, out);
12771338
}
12781339

1279-
term_o open_ml(const lar_term& ml) const {
1340+
template <typename T> term_o open_ml(const T& ml) const {
12801341
term_o r;
12811342
for (const auto& p : ml) {
12821343
r += p.coeff() * (lra.get_term(p.var()) - lar_term(p.var()));
@@ -1319,7 +1380,7 @@ namespace lp {
13191380
e.m_c = r;
13201381
m_e_matrix.add_new_element(h, xt, ahk);
13211382

1322-
m_entries.push_back({lar_term(), q, entry_status::NO_S_NO_F});
1383+
m_entries.push_back({q, entry_status::NO_S_NO_F});
13231384
m_e_matrix.add_new_element(fresh_row, xt, -mpq(1));
13241385
m_e_matrix.add_new_element(fresh_row, k, mpq(1));
13251386
for (unsigned i : m_indexed_work_vector.m_index) {
@@ -1359,9 +1420,9 @@ namespace lp {
13591420
// out << "\tstatus:" << (int)e.m_entry_status;
13601421
if (need_print_dep) {
13611422
out << "\tm_l:{";
1362-
print_lar_term_L(e.m_l, out) << "}, ";
1363-
print_ml(e.m_l, out << "\n\tfixed expl of m_l:\n") << "\n";
1364-
print_dep(out, explain_fixed_in_meta_term(e.m_l)) << ",";
1423+
print_lar_term_L(l_term_from_row(ei), out) << "}, ";
1424+
print_ml(l_term_from_row(ei), out << "\n\tfixed expl of m_l:\n") << "\n";
1425+
print_dep(out, explain_fixed_in_meta_term(l_term_from_row(ei))) << ",";
13651426
}
13661427
switch (e.m_entry_status) {
13671428
case entry_status::F:
@@ -1436,7 +1497,7 @@ namespace lp {
14361497
TRACE("dioph_eq", tout << "conflict:";
14371498
print_entry(m_conflict_index, tout, true) << std::endl;);
14381499
auto& ep = m_entries[m_conflict_index];
1439-
for (auto ci : lra.flatten(explain_fixed_in_meta_term(ep.m_l))) {
1500+
for (auto ci : lra.flatten(explain_fixed_in_meta_term(m_l_matrix.m_rows[m_conflict_index]))) {
14401501
ex.push_back(ci);
14411502
}
14421503
TRACE("dioph_eq", lra.print_expl(tout, ex););

src/math/lp/lar_solver.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55
#include "math/lp/lar_solver.h"
66
#include "smt/params/smt_params_helper.hpp"
7+
#include "lar_solver.h"
78

89

910
namespace lp {
@@ -1598,6 +1599,12 @@ namespace lp {
15981599
bool lar_solver::external_is_used(unsigned v) const {
15991600
return m_var_register.external_is_used(v);
16001601
}
1602+
void lar_solver::register_add_term_delegate(const std::function<void(const lar_term*)>& f) {
1603+
this->m_add_term_delegates.push_back(f);
1604+
}
1605+
void lar_solver::register_add_column_bound_delegate(const std::function<void(unsigned)>& f) {
1606+
this->m_add_column_bound_delegates.push_back(f);
1607+
}
16011608

16021609
void lar_solver::add_non_basic_var_to_core_fields(unsigned ext_j, bool is_int) {
16031610
register_new_external_var(ext_j, is_int);
@@ -1695,6 +1702,8 @@ namespace lp {
16951702
lp_assert(m_var_register.size() == A_r().column_count());
16961703
if (m_need_register_terms)
16971704
register_normalized_term(*t, A_r().column_count() - 1);
1705+
for (const auto & f: m_add_term_delegates)
1706+
f(t);
16981707
return ret;
16991708
}
17001709

@@ -1742,6 +1751,8 @@ namespace lp {
17421751
constraint_index lar_solver::add_var_bound(lpvar j, lconstraint_kind kind, const mpq& right_side) {
17431752
constraint_index ci = mk_var_bound(j, kind, right_side);
17441753
activate(ci);
1754+
for (const auto & f: m_add_column_bound_delegates)
1755+
f(j);
17451756
return ci;
17461757
}
17471758

src/math/lp/lar_solver.h

+7
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,13 @@ class lar_solver : public column_namer {
405405
}
406406
}
407407

408+
void register_add_term_delegate(const std::function<void (const lar_term*)>&);
409+
void register_add_column_bound_delegate(const std::function<void (unsigned)>&);
410+
411+
private:
412+
std_vector<std::function<void (const lar_term*)>> m_add_term_delegates;
413+
std_vector<std::function<void (unsigned)>> m_add_column_bound_delegates;
414+
public:
408415
bool external_is_used(unsigned) const;
409416
void pop(unsigned k);
410417
unsigned num_scopes() const { return m_trail.get_num_scopes(); }

src/math/lp/static_matrix.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,7 @@ template bool lp::static_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >::pivot_row_
5656
template void lp::static_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >::pivot_row_to_row_given_cell_with_sign(unsigned int, column_cell&, unsigned int, int);
5757
template void lp::static_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >::remove_element(vector<lp::row_cell<lp::mpq>, true, unsigned int>&, lp::row_cell<lp::mpq>&);
5858
template void lp::static_matrix<mpq, mpq>::pivot_row_to_row_given_cell_with_sign(unsigned int, lp::row_cell<lp::empty_struct>&, unsigned int, int);
59+
template void lp::static_matrix<lp::mpq, lp::numeric_pair<lp::mpq> >::add_rows(mpq const&, unsigned int, unsigned int);
60+
template void lp::static_matrix<lp::mpq,lp::mpq>::add_rows(class rational const &,unsigned int,unsigned int);
5961
}
6062

0 commit comments

Comments
 (0)