00001
00002
00003
00004
00005
00006
00007
00008 #include "Equation.h"
00009 #include <unordered_map>
00010 #include <set>
00011 #include <map>
00012 #include <list>
00013
00014
00015 typedef unordered_map<Equation*, bignum, hash<Equation*>, equation_eq> eq_map;
00016
00017 #ifndef BIG_MATRIX_H_
00018 #define BIG_MATRIX_H_
00019
00020 #define MATRIX_ASSERT false
00021
00022 #define REAL (1)
00023 #define IGNORED (1<<1)
00024
00025
00026
00027 class Matrix {
00028
00029 public:
00030 class iterator
00031 {
00032 friend class Matrix;
00033 private:
00034 set<pair<int, Equation*> >::iterator it;
00035 Matrix & m;
00036 iterator(set<pair<int, Equation*> >::iterator it, Matrix & m):
00037 it(it), m(m)
00038 {
00039
00040 }
00041 public:
00042 pair<Equation* const, bignum> *operator->()
00043 {
00044 if(MATRIX_ASSERT) assert(m.equations.count(it->second) > 0);
00045 return &(*m.equations.find(it->second));
00046 }
00047 pair<Equation*, bignum> operator*()
00048 {
00049 if(MATRIX_ASSERT) assert(m.equations.count(it->second) > 0);
00050 return *m.equations.find(it->second);
00051 }
00052 const void operator++(int i)
00053 {
00054 it++;
00055 while(it != m.ordered_eqs.end() && m.ignored.count(it->second) >0){
00056 it++;
00057 }
00058
00059 }
00060 bool operator==(iterator other)
00061 {
00062 return (it == other.it);
00063 }
00064 bool operator!=(iterator other)
00065 {
00066 return (it != other.it);
00067 }
00068
00069 };
00070
00071
00072
00073 private:
00074 vector<string> vars;
00075 vector<string>& original_vars;
00076 map<int, int> old_to_new_vars;
00077 map<int, Equation*> index_to_sub;
00078 vector<int> substitution_order;
00079 set<Equation*> initial_eq;
00080 bool initial;
00081 eq_map equations;
00082 int eq_count;
00083 set<pair<int, Equation*> > ordered_eqs;
00084 map<Equation*, int> eq_to_time;
00085
00086
00087
00088
00089 set<Equation*> ignored;
00090
00091 list<pair<Equation*, int> > eq_stack;
00092 map<Equation*, list<bignum> > history;
00093 public:
00094 inline Matrix(vector<string>& vars):vars(vars), original_vars(vars)
00095 {
00096 initial = true;
00097 eq_count = 0;
00098 }
00099
00100 inline Matrix(Matrix & other):vars(other.vars),
00101 original_vars(other.original_vars)
00102 {
00103 eq_count = 0;
00104 initial = other.initial;
00105 iterator it = other.begin();
00106 for(; it!= other.end(); it++) {
00107 Equation* eq = it->first->clone();
00108 insert(eq, it->second);
00109 }
00110
00111 }
00112
00113 inline int num_initial_equations()
00114 {
00115 return initial_eq.size();
00116 }
00117
00118
00119
00120 inline void end_initial()
00121 {
00122 initial = false;
00123 }
00124
00125 inline int num_vars()
00126 {
00127 return vars.size();
00128 }
00129
00130 inline bool ignored_set_empty()
00131 {
00132 return ignored.size() == 0;
00133 }
00134
00135 inline vector<string>& get_vars()
00136 {
00137 return vars;
00138 }
00139
00140 void check_consistency()
00141 {
00142 set<Equation*> old_eqs;
00143 eq_map::iterator it = equations.begin();
00144 for(;it != equations.end();it++){
00145 if(ignored.count(it->first) >0) continue;
00146 old_eqs.insert(it->first);
00147 }
00148
00149 set<Equation*> new_eqs;
00150 set<pair<int, Equation*> >::iterator i2 = ordered_eqs.begin();
00151 for(; i2 != ordered_eqs.end(); i2++) {
00152 if(ignored.count(i2->second) >0) continue;
00153 new_eqs.insert(i2->second);
00154 }
00155 if(old_eqs.size() != new_eqs.size()){
00156 cout << "Assertion failed: OLD EQ SIZE: " << old_eqs.size() <<
00157 " NEW EQ SIZE: " << new_eqs.size() << endl;
00158 assert(false);
00159 }
00160 assert(old_eqs == new_eqs);
00161 }
00162
00163 inline iterator begin()
00164 {
00165
00166 if(MATRIX_ASSERT) check_consistency();
00167
00168 set<pair<int, Equation*> >::iterator it = ordered_eqs.begin();
00169 while(it != ordered_eqs.end() && ignored.count(it->second) >0){
00170 it++;
00171 }
00172 return iterator(it, *this);
00173 }
00174 inline iterator end()
00175 {
00176 return iterator(ordered_eqs.end(), *this);
00177 }
00178
00179 inline int size()
00180 {
00181 return equations.size()-ignored.size();
00182
00183 }
00184
00185 inline void simplify()
00186 {
00187 map<Equation*, bignum> old_equations;
00188 old_equations.insert(equations.begin(), equations.end());
00189 equations.clear();
00190 ordered_eqs.clear();
00191 eq_to_time.clear();
00192 std::set<Equation*> to_delete;
00193 map<Equation*, bignum>::iterator it = old_equations.begin();
00194 for(; it!= old_equations.end(); it++)
00195 {
00196 Equation* eq = it->first;
00197 bignum constant = it->second;
00198 bignum gcd = eq->compute_gcd();
00199 bignum total_gcd = gcd.compute_gcd(constant);
00200 if(total_gcd == 0) continue;
00201 if(total_gcd == 1){
00202 insert(eq, constant);
00203 continue;
00204 }
00205 Equation* new_eq = new Equation(eq->get_cols());
00206 for(int i=0; i < eq->get_cols(); i++) {
00207 new_eq->set(i, eq->get(i)/total_gcd);
00208 }
00209 insert(new_eq, constant/total_gcd);
00210 to_delete.insert(eq);
00211 }
00212 set<Equation*>::iterator it2 = to_delete.begin();
00213 for(; it2!= to_delete.end(); it2++) {
00214 delete *it2;
00215 }
00216 if(MATRIX_ASSERT) check_consistency();
00217 }
00218
00219 inline void insert(Equation*& eq, bignum constant)
00220 {
00221 if(eq_stack.size() >0){
00222 push_equation_internal(eq, constant, false);
00223 return;
00224 }
00225 insert_internal(eq, constant);
00226 }
00227
00228 inline void insert_internal(Equation*& eq, bignum constant)
00229 {
00230 if(MATRIX_ASSERT) assert(eq->get_cols() == (int)vars.size());
00231 if(equations.count(eq) == 0){
00232 if(MATRIX_ASSERT){
00233 assert(eq_to_time.count(eq) == 0);
00234 }
00235 int time_stamp = eq_count++;
00236 equations[eq] = constant;
00237 ordered_eqs.insert(pair<int, Equation*>(time_stamp, eq));
00238 eq_to_time[eq] = time_stamp;
00239 if(initial) initial_eq.insert(eq);
00240 }
00241 else {
00242 Equation* old_eq = equations.find(eq)->first;
00243 if(MATRIX_ASSERT){
00244 assert(eq_to_time.count(old_eq) > 0);
00245 }
00246 bignum old_c = equations[old_eq];
00247 if(constant<old_c){
00248 if(MATRIX_ASSERT){
00249 assert(eq_to_time.count(old_eq) > 0);
00250 }
00251 equations[old_eq] = constant;
00252 if(initial) initial_eq.insert(old_eq);
00253
00254 }
00255 delete eq;
00256 }
00257 eq = NULL;
00258 }
00259
00260 inline bool is_initial(Equation* e)
00261 {
00262 return initial_eq.count(e) !=0;
00263 }
00264
00265
00266
00267 inline void push_equation(Equation* eq, bignum constant)
00268 {
00269 push_equation_internal(eq, constant, true);
00270 }
00271
00272 inline void push_equation_internal(Equation* eq, bignum constant, bool real)
00273 {
00274
00275 int attribute = 0;
00276 if(real) attribute |= REAL;
00277 Equation* existing = get(eq);
00278 if(existing == NULL) {
00279 if(MATRIX_ASSERT){
00280 assert(eq_to_time.count(eq) == 0);
00281 }
00282 int time_stamp = eq_count++;
00283 eq_to_time[eq] = time_stamp;
00284 ordered_eqs.insert(pair<int, Equation*>(time_stamp, eq));
00285
00286 equations[eq] = constant;
00287 eq_stack.push_front(pair<Equation*, bool>(eq, attribute));
00288 return;
00289 }
00290
00291 if(MATRIX_ASSERT){
00292 assert(eq_to_time.count(existing) > 0);
00293 }
00294 if(ignored.count(existing) > 0){
00295 attribute |= IGNORED;
00296 ignored.erase(existing);
00297 }
00298 bignum old_c = get_constant(eq);
00299 delete eq;
00300 if(old_c <= constant){
00301 assert(false);
00302 eq_stack.push_front(pair<Equation*, bool>((Equation*)NULL, attribute));
00303 return;
00304 }
00305 equations[existing] = constant;
00306 history[existing].push_front(old_c);
00307 eq_stack.push_front(pair<Equation*, bool>(existing, attribute));
00308 }
00309
00310 inline void pop_equation()
00311 {
00312 while(true)
00313 {
00314 Equation* eq = eq_stack.front().first;
00315 int attribute = eq_stack.front().second;
00316 bool real = attribute & REAL;
00317 bool is_ignored = attribute & IGNORED;
00318
00319 eq_stack.pop_front();
00320 if(eq == NULL){
00321 if(real) return;
00322 continue;
00323 }
00324
00325 if(history.count(eq) == 0) {
00326 if(MATRIX_ASSERT) assert(equations.count(eq));
00327 if(MATRIX_ASSERT) {
00328 assert(eq_to_time.count(eq) > 0);
00329 }
00330 int old_time_stamp = eq_to_time[eq];
00331 pair<int, Equation*> p(old_time_stamp, eq);
00332 if(MATRIX_ASSERT) assert(ordered_eqs.count(p) > 0);
00333 ordered_eqs.erase(p);
00334 eq_to_time.erase(eq);
00335 assert(!is_ignored);
00336 assert(equations.count(eq) >0);
00337 equations.erase(eq);
00338 delete eq;
00339 if(real) return;
00340 continue;
00341 }
00342 bignum old_c = history[eq].front();
00343 history[eq].pop_front();
00344 if(history[eq].size() == 0)
00345 history.erase(eq);
00346 equations[eq] = old_c;
00347 if(is_ignored) ignored.insert(eq);
00348 if(real) return;
00349 }
00350 }
00351
00352 inline void set_value(Equation* eq, bignum constant)
00353 {
00354 if(MATRIX_ASSERT) assert(contains(eq));
00355 equations[eq] = constant;
00356 }
00357
00358 inline bool contains(Equation* eq)
00359 {
00360 return equations.count(eq)>0;
00361 }
00362
00363 inline bool contains(Equation* eq, bignum constant)
00364 {
00365 if(!contains(eq)) return false;
00366 return equations[eq] == constant;
00367 }
00368
00369 inline Equation* get(Equation* eq)
00370 {
00371 if(!contains(eq)) return NULL;
00372 return equations.find(eq)->first;
00373 }
00374
00375 inline bool contains_negative(Equation* eq, bignum constant)
00376 {
00377 Equation neg_eq(vars.size());
00378 for(int c=0; c<eq->get_cols(); c++)
00379 {
00380 neg_eq.set(c, -eq->get(c));
00381 }
00382 if(!contains(&neg_eq)) return false;
00383 return contains(&neg_eq, -constant);
00384 }
00385
00386 inline Equation* get_negative(Equation* eq, bignum constant)
00387 {
00388 Equation neg_eq(vars.size());
00389 for(int c=0; c<eq->get_cols(); c++)
00390 {
00391 neg_eq.set(c, -eq->get(c));
00392 }
00393 if(!contains(&neg_eq)) return NULL;
00394 Equation* res = equations.find(&neg_eq)->first;
00395 bignum c2 = equations.find(&neg_eq)->second;
00396 if(c2 == -constant) return res;
00397 return NULL;
00398 }
00399
00400
00401
00402
00403 inline bool is_redundant(Equation* eq, bignum constant)
00404 {
00405 if(equations.count(eq) == 0) return false;
00406 bignum existing_const = equations[eq];
00407 return (existing_const <= constant);
00408 }
00409
00410 inline bignum get_constant(Equation* eq)
00411 {
00412 if(MATRIX_ASSERT) assert(equations.count(eq) > 0);
00413 return equations[eq];
00414 }
00415
00416 inline bool remove(Equation* eq)
00417 {
00418
00419 if(!contains(eq)) return false;
00420 Equation* old_eq = equations.find(eq)->first;
00421 assert(ignored.count(old_eq)==0);
00422 if(MATRIX_ASSERT) assert(equations.count(old_eq)>0);
00423 equations.erase(old_eq);
00424 if(MATRIX_ASSERT){
00425 assert(eq_to_time[old_eq] > 0);
00426 }
00427 int old_time_stamp = eq_to_time[old_eq];
00428 pair<int, Equation*> p(old_time_stamp, old_eq);
00429 if(MATRIX_ASSERT) {
00430 assert(ordered_eqs.count(p) > 0);
00431 }
00432 ordered_eqs.erase(p);
00433 eq_to_time.erase(old_eq);
00434 delete old_eq;
00435 return true;
00436 }
00437
00438 inline bool remove(Equation* eq, bignum constant)
00439 {
00440 if(!contains(eq)) return false;
00441 Equation* old_eq = equations.find(eq)->first;
00442 assert(ignored.count(old_eq)==0);
00443 if(equations.find(eq)->second != constant) return false;
00444 equations.erase(old_eq);
00445 if(MATRIX_ASSERT){
00446 assert(eq_to_time[old_eq] > 0);
00447 }
00448 int old_time_stamp = eq_to_time[old_eq];
00449 pair<int, Equation*> p(old_time_stamp, old_eq);
00450 if(MATRIX_ASSERT) assert(ordered_eqs.count(p) > 0);
00451 ordered_eqs.erase(p);
00452 eq_to_time.erase(old_eq);
00453 delete old_eq;
00454 return true;
00455 }
00456
00457 string to_string()
00458 {
00459 string res;
00460 for(unsigned int i=0; i < vars.size(); i++) {
00461 res+= vars[i] + "\t";
00462 }
00463 res+= "[c]\n";
00464 eq_map::iterator it = equations.begin();
00465 for(; it!= equations.end(); it++) {
00466 res+=it->first->to_string();
00467 res+=it->second.to_string();
00468 res+="\n";
00469 }
00470 return res;
00471 }
00472
00473 friend ostream& operator <<(ostream &os,const Matrix &obj);
00474
00475
00476 inline ~Matrix()
00477 {
00478
00479 eq_map::iterator it = equations.begin();
00480 set<Equation*> to_delete;
00481 for(; it != equations.end(); it++) {
00482 to_delete.insert(it->first);
00483 }
00484 set<Equation*>::iterator it2 = to_delete.begin();
00485 for(; it2 != to_delete.end(); it2++) {
00486 delete *it2;
00487 }
00488
00489 map<int, Equation*>::iterator it3 = index_to_sub.begin();
00490 for(; it3!= index_to_sub.end(); it3++) {
00491 delete it3->second;
00492 }
00493 }
00494
00495
00496 inline void make_diophantine()
00497 {
00498 Matrix::iterator it = begin();
00499 for(; it!= end(); it++)
00500 {
00501 Equation* eq= it->first;
00502 bignum constant = it->second;
00503 bignum coef_gcd = eq->compute_gcd();
00504 if(coef_gcd == 0 || constant.divisible(coef_gcd)) continue;
00505 bignum quotient = constant/coef_gcd;
00506 if(constant<0) quotient-=1;
00507 bignum new_c = coef_gcd*quotient;
00508 set_value(eq, new_c);
00509
00510 }
00511 simplify();
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521 void propagate_equalities(set< set< pair<Equation*, bignum> > >*
00522 neq_constraints = NULL)
00523 {
00524
00525 set<int> neq_vars;
00526 if(neq_constraints != NULL) {
00527 set<set<pair<Equation*, bignum> > >::iterator it = neq_constraints->begin();
00528 for(; it!= neq_constraints->end(); it++) {
00529 set<pair<Equation*, bignum> >::iterator it2= it->begin();
00530 for(; it2!= it->end(); it2++)
00531 {
00532 Equation* e = it2->first;
00533
00534
00535 for(int i=0;i < e->num_entries(); i++) {
00536 if(e->get(i) != 0) neq_vars.insert(i);
00537 }
00538 }
00539
00540
00541 }
00542 }
00543
00544 while(true)
00545 {
00546 Equation* eq_old = NULL;
00547 Equation* neq_old = NULL;
00548 iterator it = begin();
00549 int eliminate_index = -1;
00550 Equation* sub = NULL;
00551 bool progress = false;
00552 for(; it!= end(); it++)
00553 {
00554 eq_old = it->first;
00555 bignum constant = it->second;
00556
00557
00558
00559
00560 neq_old = get_negative(eq_old, constant);
00561 if(neq_old == NULL) continue;
00562
00563
00564
00565
00566 bool remove = false;
00567 for(int c=0; c<eq_old->num_entries(); c++)
00568 {
00569 if((eq_old->get(c) == 1 || eq_old->get(c) == -1) &&
00570 index_to_sub.count(c) == 0 && neq_vars.count(c) == 0 &&
00571 var_occurs(c, eq_old, neq_old)){
00572 remove = true;
00573 eliminate_index = c;
00574
00575
00576
00577
00578
00579 sub = new Equation(eq_old->num_entries()+1);
00580 if(eq_old->get(c) == 1)
00581 {
00582 for(int i=0; i<eq_old->num_entries(); i++){
00583 if(i == c)
00584 sub->set(i, 0);
00585 else
00586 sub->set(i, -eq_old->get(i));
00587 }
00588 sub->set(eq_old->num_entries(), constant);
00589 }
00590 else
00591 {
00592 for(int i=0; i<eq_old->num_entries(); i++){
00593 if(i == c)
00594 sub->set(i, 0);
00595 else
00596 sub->set(i, eq_old->get(i));
00597 }
00598 sub->set(eq_old->num_entries(), -constant);
00599 }
00600 index_to_sub[c] = sub;
00601 substitution_order.push_back(c);
00602
00603 break;
00604 }
00605 }
00606 if(!remove) continue;
00607 progress = true;
00608 break;
00609 }
00610 if(!progress) break;
00611 remove(eq_old);
00612 remove(neq_old);
00613 eliminate_var(eliminate_index, sub);
00614 }
00615
00616 int old_size = num_vars();
00617 vars.clear();
00618 int cur = 0;
00619
00620
00621 for(int i=0; i < old_size; i++) {
00622 if(index_to_sub.count(i) == 0){
00623 vars.push_back(original_vars[i]);
00624 old_to_new_vars[i] = cur++;
00625
00626 }
00627 else {
00628 old_to_new_vars[i] = -1;
00629
00630 }
00631 }
00632 map<Equation*, bignum> temp_map;
00633 iterator it = begin();
00634 for(; it!= end(); it++) {
00635 temp_map[it->first] = it->second;
00636 }
00637
00638 equations.clear();
00639 ordered_eqs.clear();
00640 eq_to_time.clear();
00641 int new_eq_size = vars.size();
00642
00643
00644
00645 map<Equation*, bignum>::iterator it2 = temp_map.begin();
00646 for(; it2!= temp_map.end(); it2++) {
00647 Equation* eq = it2->first;
00648 bignum constant = it2->second;
00649 Equation* new_eq = new Equation(new_eq_size);
00650 int cur = 0;
00651
00652
00653 for(int i=0; i < eq->num_entries(); i++) {
00654 if(old_to_new_vars[i]==-1){
00655 continue;
00656 }
00657
00658 new_eq->set(cur++, eq->get(i));
00659 }
00660
00661 insert(new_eq, constant);
00662 delete eq;
00663 }
00664
00665 if(neq_constraints != NULL) {
00666 set<int> cols_to_remove;
00667 cols_to_remove.insert(substitution_order.begin(),
00668 substitution_order.end());
00669
00670
00671
00672
00673
00674 set< set< pair<Equation*, bignum> > > result_neq;
00675 set< set< pair<Equation*, bignum> > >::iterator it =
00676 neq_constraints->begin();
00677 for(; it!= neq_constraints->end(); it++) {
00678 set<pair<Equation*, bignum> >::iterator it2 = it->begin();
00679 set<pair<Equation*, bignum> > cur_disjunctive_ineq;
00680 for(; it2!= it->end(); it2++)
00681 {
00682 Equation* old_eq =it2->first;
00683
00684 Equation* new_eq = new Equation(vars.size());
00685
00686 int cur_index = 0;
00687
00688
00689 for(int i=0; i<old_eq->num_entries(); i++) {
00690 if(cols_to_remove.count(i) > 0) continue;
00691 new_eq->set(cur_index, old_eq->get(i));
00692 cur_index++;
00693 }
00694 cur_disjunctive_ineq.insert(pair<Equation*, bignum>(new_eq,
00695 it2->second));
00696 delete old_eq;
00697 }
00698
00699
00700 result_neq.insert(cur_disjunctive_ineq);
00701
00702 }
00703
00704 *neq_constraints = result_neq;
00705 }
00706 if(MATRIX_ASSERT) check_consistency();
00707 }
00708
00709 inline void adjust_assignments(vector<bigfraction> & assignments,
00710 vector<bignum>& final_assignments)
00711 {
00712 final_assignments.reserve(old_to_new_vars.size());
00713 map<int, bigfraction> res_assignments;
00714 map<int, int>::iterator it = old_to_new_vars.begin();
00715 for(; it != old_to_new_vars.end(); it++)
00716 {
00717 int old_index = it->first;
00718 int new_index = it->second;
00719 if(new_index == -1) continue;
00720 res_assignments[old_index] = assignments[new_index];
00721 }
00722
00723 for(int i=substitution_order.size()-1; i>=0; i--)
00724 {
00725 int old_index = substitution_order[i];
00726 Equation* sub = index_to_sub[old_index];
00727 int num_entries = sub->num_entries();
00728 bigfraction cur = 0;
00729 for(int j=0; j<num_entries-1; j++)
00730 {
00731 bigfraction coef = sub->get(j);
00732 if(coef == 0) continue;
00733 assert(res_assignments.count(j) != 0);
00734 cur += coef*res_assignments[j];
00735 }
00736
00737 cur += sub->get(num_entries-1);
00738 res_assignments[old_index] = cur;
00739
00740 }
00741
00742 map<int, bigfraction>::iterator it2 = res_assignments.begin();
00743 for(; it2!= res_assignments.end(); it2++) {
00744 bigfraction& f = it2->second;
00745 bignum n = f.get_numerator();
00746 bignum d = f.get_denominator();
00747 if(d!=1) {
00748 cerr << "n: " << n << " d: " << d << endl;
00749 assert(false);
00750 }
00751 final_assignments.push_back(n);
00752 }
00753
00754 }
00755
00756 inline bool var_occurs(int index, Equation* eq1, Equation* eq2)
00757 {
00758 iterator it = begin();
00759 for(; it!= end(); it++)
00760 {
00761 Equation* eq = it->first;
00762 if(eq == eq1 || eq == eq2) continue;
00763 if(eq->get(index) != 0) return true;
00764 }
00765 return false;
00766 }
00767
00768
00769 void eliminate_var(int i, Equation* sub)
00770 {
00771
00772 map<Equation*, bignum> temp_map;
00773 iterator it = begin();
00774 for(; it!= end(); it++) {
00775 temp_map[it->first] = it->second;
00776 }
00777 equations.clear();
00778 ordered_eqs.clear();
00779 eq_to_time.clear();
00780
00781 map<Equation*, bignum>::iterator it2 = temp_map.begin();
00782 for(; it2!= temp_map.end(); it2++) {
00783 Equation* eq = it2->first;
00784 bignum constant = it2->second;
00785 bignum factor = eq->get(i);
00786 if(factor == 0){
00787 insert(eq, constant);
00788 continue;
00789 }
00790 for(int c=0; c<eq->num_entries(); c++) {
00791 bignum val = 0;
00792 if(c != i)
00793 val = eq->get(c);
00794 eq->set(c, val+sub->get(c)*factor);
00795 }
00796 constant-=sub->get(eq->num_entries())*factor;
00797 insert(eq, constant);
00798 }
00799
00800 if(MATRIX_ASSERT) check_consistency();
00801 }
00802
00803
00804 inline void mark_current_facets(vector<bigfraction>& assignments)
00805 {
00806 eq_map::iterator it = equations.begin();
00807 for(; it!= equations.end(); it++)
00808 {
00809 Equation* eq = it->first;
00810 bignum constant = it->second;
00811 bigfraction lhs = eq->evaluate(assignments);
00812 if(lhs != constant) ignored.insert(eq);
00813 }
00814 }
00815
00816 inline void clear_current_facets()
00817 {
00818 ignored.clear();
00819 }
00820 };
00821
00822 #endif