00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 #define __STDC_LIMIT_MACROS
00083 #include <stdint.h>
00084 #include <sys/types.h>
00085
00086 #include "soe.h"
00087
00088 #include "tracing.h"
00089 #define TT_LNO_DEP2 0x00000002 // from lnopt_main.cxx
00090
00091 #ifdef LNO
00092 #include "ipa_lno_util.h"
00093 #endif
00094
00095 #ifdef KEY
00096 #include "config.h"
00097 #endif
00098
00099
00100
00101
00102
00103 #ifndef LNO
00104 inline mINT32 myabs(mINT32 i)
00105 {
00106 return i < 0 ? -i : i;
00107 }
00108
00109 inline mINT64 myabs(mINT64 i)
00110 {
00111 return i < 0 ? -i : i;
00112 }
00113
00114
00115 static
00116 INT32 Gcd(mINT32 i, mINT32 j)
00117 {
00118 i = myabs(i);
00119 j = myabs(j);
00120
00121 if (i == 0)
00122 return j;
00123 if (j == 0)
00124 return i;
00125
00126 if (i > j) {
00127 INT32 t = i;
00128 i = j;
00129 j = t;
00130 }
00131
00132 do {
00133 INT32 t = i;
00134 i = j%i;
00135 j = t;
00136 } while (i);
00137
00138 return j;
00139 }
00140
00141 static
00142 INT64 Gcd(mINT64 i, mINT64 j)
00143 {
00144 i = myabs(i);
00145 j = myabs(j);
00146
00147 if (i == 0)
00148 return j;
00149 if (j == 0)
00150 return i;
00151
00152 if (i > j) {
00153 INT64 t = i;
00154 i = j;
00155 j = t;
00156 }
00157
00158 do {
00159 INT64 t = i;
00160 i = j%i;
00161 j = t;
00162 } while (i);
00163
00164 return j;
00165 }
00166
00167 #endif
00168
00169 SYSTEM_OF_EQUATIONS::SYSTEM_OF_EQUATIONS(const SYSTEM_OF_EQUATIONS *soe,
00170 MEM_POOL *pool) : _Ale(soe->_Ale,pool), _Aeq(soe->_Aeq,pool)
00171 {
00172 _pool = pool;
00173
00174
00175
00176 _ble = CXX_NEW_ARRAY(mINT64,soe->_eqns_le_stored,pool);
00177 _beq = CXX_NEW_ARRAY(mINT64,soe->_eqns_eq_stored,pool);
00178 INT32 i;
00179 for (i=0; i<soe->_eqns_le; i++) {
00180 _ble[i] = soe->_ble[i];
00181 }
00182 for (i=0; i<soe->_eqns_eq; i++) {
00183 _beq[i] = soe->_beq[i];
00184 }
00185 _eqns_eq = soe->_eqns_eq;
00186 _eqns_eq_stored = soe->_eqns_eq_stored;
00187 _eqns_le = soe->_eqns_le;
00188 _eqns_le_stored = soe->_eqns_le_stored;
00189 _vars = soe->_vars;
00190 }
00191
00192 void SYSTEM_OF_EQUATIONS::Add_Vars(const INT32 num_vars)
00193 {
00194 if (_Ale.Cols() < (_vars+num_vars)) _Ale.D_Add_Cols(num_vars);
00195 if (_Aeq.Cols() < (_vars+num_vars)) _Aeq.D_Add_Cols(num_vars);
00196
00197
00198 INT32 i;
00199 for (i=0; i<_eqns_le; i++) {
00200 for (INT32 j=_vars; j<_vars+num_vars; j++) {
00201 _Ale(i,j) = 0;
00202 }
00203 }
00204 for (i=0; i<_eqns_eq; i++) {
00205 for (INT32 j=_vars; j<_vars+num_vars; j++) {
00206 _Aeq(i,j) = 0;
00207 }
00208 }
00209 _vars += num_vars;
00210 }
00211
00212 void SYSTEM_OF_EQUATIONS::Remove_Last_Vars(INT num_vars)
00213 {
00214 FmtAssert(num_vars <= _vars,("Removed more variables than exist"));
00215
00216
00217 INT32 i;
00218 for (i=0; i<_eqns_le; i++) {
00219 for (INT32 j=_vars-num_vars; j<_vars; j++) {
00220 FmtAssert(_Ale(i,j) == 0,("Removed a used variable"));
00221 _Ale(i,j) = 0;
00222 }
00223 }
00224 for (i=0; i<_eqns_eq; i++) {
00225 for (INT32 j=_vars-num_vars; j<_vars; j++) {
00226 FmtAssert(_Aeq(i,j) == 0,("Removed a used variable"));
00227 _Aeq(i,j) = 0;
00228 }
00229 }
00230 _vars -= num_vars;
00231 }
00232
00233 void SYSTEM_OF_EQUATIONS::Add_Eq(const mINT32 row[], INT64 b)
00234 {
00235 if (_eqns_eq + 1 > _eqns_eq_stored) {
00236 _Aeq.D_Add_Rows(ROW_INCR());
00237 _eqns_eq_stored += ROW_INCR();
00238 INT64 *tmp = CXX_NEW_ARRAY(mINT64,_eqns_eq_stored,_pool);
00239 for (INT32 i=0; i<_eqns_eq; i++) {
00240 tmp[i] = _beq[i];
00241 }
00242 CXX_DELETE_ARRAY(_beq,_pool);
00243 _beq = tmp;
00244 }
00245 for (INT32 i=0; i<_vars; i++) {
00246 _Aeq(_eqns_eq,i) = row[i];
00247 }
00248 _beq[_eqns_eq++] = b;
00249 }
00250
00251 void SYSTEM_OF_EQUATIONS::Add_Eq(INT num_rows)
00252 {
00253 if (_eqns_eq + num_rows > _eqns_eq_stored) {
00254 _Aeq.D_Add_Rows(MAX(_eqns_eq+num_rows-_eqns_eq_stored,ROW_INCR()));
00255 _eqns_eq_stored += MAX(_eqns_eq+num_rows-_eqns_eq_stored,ROW_INCR());
00256 INT64 *tmp = CXX_NEW_ARRAY(mINT64,_eqns_eq_stored,_pool);
00257 for (INT32 i=0; i<_eqns_eq; i++) {
00258 tmp[i] = _beq[i];
00259 }
00260 CXX_DELETE_ARRAY(_beq,_pool);
00261 _beq = tmp;
00262 }
00263 _eqns_eq += num_rows;
00264 }
00265
00266 void SYSTEM_OF_EQUATIONS::Add_Le(const mINT32 row[], INT64 b)
00267 {
00268 if (_eqns_le >= _eqns_le_stored) {
00269 _Ale.D_Add_Rows(ROW_INCR());
00270 _eqns_le_stored += ROW_INCR();
00271 INT64 *tmp = CXX_NEW_ARRAY(mINT64,_eqns_le_stored,_pool);
00272 for (INT32 i=0; i<_eqns_le; i++) {
00273 tmp[i] = _ble[i];
00274 }
00275 CXX_DELETE_ARRAY(_ble,_pool);
00276 _ble = tmp;
00277 }
00278 for (INT32 i=0; i<_vars; i++) {
00279 _Ale(_eqns_le,i) = row[i];
00280 }
00281
00282
00283
00284 _ble[_eqns_le++] = b;
00285 }
00286
00287 BOOL SYSTEM_OF_EQUATIONS::Add_Le_Non_Redundant(const mINT32 row[], INT64 b)
00288 {
00289 BOOL rv;
00290 INT newrow = Num_Le_Constraints();
00291
00292 Add_Le(row, b);
00293 Complement_Le(newrow);
00294 if (Is_Consistent()) {
00295 rv = TRUE;
00296 Complement_Le(newrow);
00297 }
00298 else {
00299 rv = FALSE;
00300 Remove_Last_Le();
00301 }
00302
00303 return rv;
00304 }
00305
00306 void SYSTEM_OF_EQUATIONS::Add_Le(INT num_rows)
00307 {
00308 if (_eqns_le + num_rows > _eqns_le_stored) {
00309 _Ale.D_Add_Rows(MAX(_eqns_le+num_rows-_eqns_le_stored,ROW_INCR()));
00310 _eqns_le_stored += MAX(_eqns_le+num_rows-_eqns_le_stored,ROW_INCR());
00311 INT64 *tmp = CXX_NEW_ARRAY(mINT64,_eqns_le_stored,_pool);
00312 for (INT32 i=0; i<_eqns_le; i++) {
00313 tmp[i] = _ble[i];
00314 }
00315 CXX_DELETE_ARRAY(_ble,_pool);
00316 _ble = tmp;
00317 }
00318 _eqns_le += num_rows;
00319 }
00320
00321 void SYSTEM_OF_EQUATIONS::Add_Soe(const SYSTEM_OF_EQUATIONS* soe)
00322 {
00323 INT32 r;
00324 FmtAssert(Num_Vars() == soe->Num_Vars(), ("Incompatable soe's in Add_Soe"));
00325
00326 for (r = 0; r < soe->Num_Le_Constraints(); r++)
00327 Add_Le(&soe->_Ale(r,0), soe->_ble[r]);
00328 for (r = 0; r < soe->Num_Eq_Constraints(); r++)
00329 Add_Eq(&soe->_Aeq(r,0), soe->_beq[r]);
00330 }
00331
00332
00333 void SYSTEM_OF_EQUATIONS::Zero_Row_Le(INT32 r)
00334 {
00335 for (INT32 c = 0; c < Num_Vars(); c++)
00336 _Ale(r,c) = 0;
00337 _ble[r] = 0;
00338 }
00339
00340 void SYSTEM_OF_EQUATIONS::Complement_Le(INT32 r)
00341 {
00342 for (INT32 c = 0; c < Num_Vars(); c++)
00343 _Ale(r,c) = -_Ale(r,c);
00344 _ble[r] = -_ble[r] - 1;
00345 }
00346
00347 INT32 SYSTEM_OF_EQUATIONS::Leftmost_Non_Zero_Le(INT32 r) const
00348 {
00349 INT32 c;
00350 for (c = 0; c < Num_Vars(); c++)
00351 if (_Ale(r,c))
00352 break;
00353 return c;
00354 }
00355
00356 void SYSTEM_OF_EQUATIONS::Sort_Le(INT* sort_criteria, BOOL descending)
00357 {
00358
00359
00360 INT rows = Num_Le_Constraints();
00361 INT cols = Num_Vars();
00362
00363 for (INT i = 0; i < rows-1; i++) {
00364
00365
00366
00367 INT mx = i;
00368 for (INT j = i+1; j < rows; j++) {
00369 if (!descending) {
00370 if (sort_criteria[j] < sort_criteria[mx])
00371 mx = j;
00372 }
00373 else {
00374 if (sort_criteria[j] > sort_criteria[mx])
00375 mx = j;
00376 }
00377 }
00378
00379
00380
00381 if (mx != i) {
00382 INT ts = sort_criteria[mx];
00383 sort_criteria[mx] = sort_criteria[i];
00384 sort_criteria[i] = ts;
00385
00386 INT64 tmp = _ble[i];
00387 _ble[i] = _ble[mx];
00388 _ble[mx] = tmp;
00389
00390 for (INT32 c = 0; c < cols; c++) {
00391 INT32 tmp = _Ale(i,c);
00392 _Ale(i,c) = _Ale(mx,c);
00393 _Ale(mx,c) = tmp;
00394 }
00395 }
00396 }
00397 }
00398
00399
00400 void SYSTEM_OF_EQUATIONS::Print(FILE *fp) const
00401 {
00402 fprintf(fp,"\n\tAle, ble is \n");
00403 INT32 i;
00404 for (i=0; i<_eqns_le; i++) {
00405 fprintf(fp, "\t");
00406 for (INT32 j=0; j<_vars; j++) {
00407 fprintf(fp," %d ",_Ale(i,j));
00408 }
00409 fprintf(fp," %lld \n",_ble[i]);
00410 }
00411 fprintf(fp,"\n");
00412
00413 if (_eqns_eq == 0) return;
00414 fprintf(fp,"\tAeq,beq is \n");
00415 for (i=0; i<_eqns_eq; i++) {
00416 fprintf(fp, "\t");
00417 for (INT32 j=0; j<_vars; j++) {
00418 fprintf(fp," %d ",_Aeq(i,j));
00419 }
00420 fprintf(fp," %lld \n",_beq[i]);
00421 }
00422
00423 }
00424
00425 void SYSTEM_OF_EQUATIONS::Print_Work(FILE *fp)
00426 {
00427 fprintf(fp,"work_le,const_le is \n");
00428 INT32 i;
00429 for (i=0; i<_work_rows; i++) {
00430 for (INT32 j=0; j<_work_cols; j++) {
00431 fprintf(fp," %d ",_work[i][j]);
00432 }
00433 fprintf(fp," %lld \n",_work_const[i]);
00434 }
00435 fprintf(fp,"\n");
00436 if (_work_rows_eq ==0) return;
00437
00438 fprintf(fp,"work_eq, const_eq is \n");
00439 for (i=0; i<_work_rows_eq; i++) {
00440 for (INT32 j=0; j<_work_cols; j++) {
00441 fprintf(fp," %d ",_work_eq[i][j]);
00442 }
00443 fprintf(fp," %lld \n",_work_const_eq[i]);
00444 }
00445 fprintf(fp,"\n");
00446 }
00447
00448
00449 BOOL SYSTEM_OF_EQUATIONS::Copy_To_Work()
00450 {
00451 if ( _vars > SOE_MAX_WORK_COLS) return(FALSE);
00452 _work_cols = _vars;
00453 _work_rows = 0;
00454 return(Copy_To_Work(0,_eqns_le-1));
00455 }
00456
00457
00458 void SYSTEM_OF_EQUATIONS::Add_Work_Le()
00459 {
00460 if (_work_cols > _vars) {
00461 Add_Vars(_work_cols - _vars +1);
00462 }
00463
00464 if (_work_cols < _vars) {
00465 for (INT r = 0; r < _work_rows; r++)
00466 for (INT j = _work_cols; j < _vars; j++)
00467 _work[r][j] = 0;
00468 }
00469
00470 for (INT r = 0; r < _work_rows; r++) {
00471 Add_Le(&_work[r][0], _work_const[r]);
00472 }
00473 }
00474
00475
00476
00477
00478
00479
00480 void SYSTEM_OF_EQUATIONS::Add_Work_Le_Non_Simple_Redundant()
00481 {
00482 if (_work_cols > _vars) {
00483 Add_Vars(_work_cols - _vars +1);
00484 }
00485
00486 if (_work_cols < _vars) {
00487 for (INT r = 0; r < _work_rows; r++)
00488 for (INT j = _work_cols; j < _vars; j++)
00489 _work[r][j] = 0;
00490 }
00491
00492 INT eqns = _eqns_le;
00493 INT r;
00494 for (r = 0; r < _work_rows; r++) {
00495 INT e;
00496 for (e = 0; e < eqns; e++) {
00497 INT rd = Is_Simple_Redundant(&_work[r][0], &_Ale(e,0),
00498 _work_const[r], _ble[e],
00499 0, _vars);
00500 if (rd == 1) {
00501 break;
00502 }
00503 else if (rd == 2) {
00504 for (INT c = 0; c < _vars; c++)
00505 _Ale(e,c) = _work[r][c];
00506 _ble[e] = _work_const[r];
00507 break;
00508 }
00509 }
00510 if (e == eqns)
00511 Add_Le(&_work[r][0], _work_const[r]);
00512 }
00513 }
00514
00515
00516
00517
00518
00519 BOOL SYSTEM_OF_EQUATIONS::Is_Consistent()
00520 {
00521 BOOL proved_inconsistent;
00522 if (!Copy_To_Work()) return(TRUE);
00523 if (!Sub_In_Equal(&proved_inconsistent)) return(TRUE);
00524 if (proved_inconsistent) return(FALSE);
00525 return(Is_Consistent_Work());
00526 }
00527
00528
00529
00530
00531
00532
00533
00534 BOOL SYSTEM_OF_EQUATIONS::Sub_In_Equal(BOOL *proved_inconsistent)
00535 {
00536 *proved_inconsistent = FALSE;
00537 if (_eqns_eq == 0) return(TRUE);
00538 if (!Copy_To_Work_Eq()) return(TRUE);
00539
00540 while (_work_rows_eq > 0) {
00541 if (!Sub_Last_Equal(proved_inconsistent)) return(FALSE);
00542 if (*proved_inconsistent) return(TRUE);
00543 }
00544 return(TRUE);
00545 }
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556 BOOL SYSTEM_OF_EQUATIONS::Project(const INT32 i,BOOL *proved_inconsistent,
00557 const INT32 min_var)
00558 {
00559 Is_True(i < _work_cols,
00560 ("Bad i for SYSTEM_OF_EQUATIONS::Project"));
00561 *proved_inconsistent = FALSE;
00562
00563
00564 INT32 last_undone = _work_rows-1;
00565 INT32 plus=0;
00566
00567 while (plus <= last_undone) {
00568 if (_work[plus][i] > 0) {
00569
00570 for (INT32 minus=0; minus <= last_undone; minus++) {
00571 if (_work[minus][i] < 0) {
00572 if (!Elim_One(i,plus,minus,proved_inconsistent,min_var)) {
00573 return(FALSE);
00574 } else if (*proved_inconsistent) {
00575 return(TRUE);
00576 }
00577 }
00578 }
00579
00580
00581 if (plus != _work_rows-1) {
00582 _work_const[plus] = _work_const[_work_rows-1];
00583 for (INT32 col=min_var; col < _work_cols; col++) {
00584 _work[plus][col] = _work[_work_rows-1][col];
00585 }
00586 if (last_undone == _work_rows-1) {
00587 last_undone--;
00588 } else {
00589 Is_True(_work[plus][i] <= 0,("Error in Project "));
00590 plus++;
00591 }
00592 } else {
00593 if (last_undone == _work_rows-1) {
00594 last_undone--;
00595 }
00596 }
00597 _work_rows--;
00598 if (_work_rows ==0) {
00599 return(TRUE);
00600 }
00601 } else {
00602 plus++;
00603 }
00604 }
00605
00606
00607 for (INT32 minus=0; minus <_work_rows; minus++) {
00608 if (_work[minus][i] < 0) {
00609 while ((minus < _work_rows-1) && _work[_work_rows-1][i] < 0) _work_rows--;
00610 if (minus < _work_rows-1) {
00611 _work_const[minus] = _work_const[_work_rows-1];
00612 for (INT32 col=min_var; col < _work_cols; col++) {
00613 _work[minus][col] = _work[_work_rows-1][col];
00614 }
00615 }
00616 _work_rows--;
00617 }
00618 }
00619 Elim_Simple_Redundant(min_var);
00620 return(TRUE);
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630 void SYSTEM_OF_EQUATIONS::Mark_Redundant(BOOL *is_redundant)
00631 {
00632 BOOL proved_inconsistent;
00633
00634 if (_eqns_le < 1) return;
00635 INT32 i;
00636 for (i=0; i<_eqns_le; i++) is_redundant[i] = FALSE;
00637
00638 for (i=0; i<_eqns_le; i++) {
00639 _work_rows = 0;
00640
00641 INT32 j;
00642 for (j=0; j<= i-1; j++) {
00643 if (!is_redundant[j]) {
00644 if (!Copy_To_Work(j,j)) return;
00645 }
00646 }
00647
00648 for (j =i+1; j<_eqns_le; j++) {
00649 if (!Copy_To_Work(j,j)) return;
00650 }
00651
00652 if (!Copy_Inverse_To_Work(i)) return;
00653 if (!Sub_In_Equal(&proved_inconsistent)) return;
00654 if (proved_inconsistent || !Is_Consistent_Work()) {
00655 is_redundant[i] = TRUE;
00656 }
00657 }
00658
00659 }
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 BOOL SYSTEM_OF_EQUATIONS::Elim_One(const INT32 i, const INT32 plus,
00672 const INT32 minus,BOOL *proved_inconsistent,
00673 const INT32 min_var)
00674 {
00675 if (_work_rows+1 >= SOE_MAX_WORK_ROWS) {
00676 return(FALSE);
00677 }
00678
00679 INT64 tmp;
00680 INT32 g = Gcd(abs(_work[plus][i]),abs(_work[minus][i]));
00681 INT64 plus_mult = _work[plus][i] / g;
00682 INT64 minus_mult = -_work[minus][i] / g;
00683
00684 _work_const[_work_rows] = minus_mult*_work_const[plus] +
00685 plus_mult*_work_const[minus];
00686
00687 BOOL has_vars = FALSE;
00688 INT32 col;
00689 for (col=0; col < min_var; col++) _work[_work_rows][col] = 0;
00690
00691 if (minus_mult == 1 && plus_mult == 1) {
00692 for (col=min_var; col < _work_cols; col++) {
00693 tmp = (INT64) _work[plus][col] + (INT64) _work[minus][col];
00694 if (abs(tmp) > INT32_MAX) return(FALSE);
00695 _work[_work_rows][col] = (INT32) tmp;
00696 if (_work[_work_rows][col] != 0) has_vars = TRUE;
00697 }
00698 } else {
00699 for (col=min_var; col < _work_cols; col++) {
00700 tmp = minus_mult*_work[plus][col] + plus_mult*_work[minus][col];
00701 if (abs(tmp) > INT32_MAX) return(FALSE);
00702 _work[_work_rows][col] = (INT32) tmp;
00703 if (_work[_work_rows][col] != 0) has_vars = TRUE;
00704 }
00705 }
00706
00707 if (!has_vars) {
00708 if (_work_const[_work_rows] < 0) {
00709 *proved_inconsistent = TRUE;
00710 return(TRUE);
00711 }
00712 } else {
00713 _work_rows++;
00714 }
00715 return(TRUE);
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 void SYSTEM_OF_EQUATIONS::Elim_Simple_Redundant(const INT32 min_var)
00727 {
00728
00729 static INT16 last_non_zero[SOE_MAX_WORK_ROWS];
00730
00731
00732
00733 INT i;
00734 for (i=0; i<_work_rows; i++) {
00735 _is_redundant[i] = FALSE;
00736 INT j = _work_cols - 1;
00737 while ((j >= min_var) && (_work[i][j] == 0)) j--;
00738 last_non_zero[i] = j;
00739 }
00740
00741
00742 for (i=0; i<_work_rows; i++) {
00743 if (!_is_redundant[i]) {
00744 for (INT32 j=i+1; j<_work_rows; j++) {
00745 if (!_is_redundant[j] && (last_non_zero[i] == last_non_zero[j])) {
00746 INT redun=Is_Simple_Redundant(&_work[i][0], &_work[j][0],
00747 _work_const[i], _work_const[j],
00748 min_var, _work_cols);
00749 if (redun==1) {
00750 _is_redundant[i] = TRUE;
00751 } else if (redun==2) {
00752 _is_redundant[j] = TRUE;
00753 }
00754
00755 #if 0
00756
00757 if (_is_redundant[i]) {
00758 _work_const[i] = _work_const[j];
00759 for (INT32 col=min_var; col<_work_cols; col++) {
00760 _work[i][col] = _work[j][col];
00761 }
00762 _is_redundant[j] = TRUE;
00763 _is_redundant[i] = FALSE;
00764 }
00765 #endif
00766
00767 }
00768 }
00769 }
00770 }
00771
00772
00773 for (i=0; i<_work_rows; i++) {
00774 if (_is_redundant[i]) {
00775 while ((i <_work_rows-1) && _is_redundant[_work_rows-1]) _work_rows--;
00776 if (i < _work_rows -1) {
00777 _work_const[i] = _work_const[_work_rows-1];
00778 for (INT32 col=min_var; col<_work_cols; col++) {
00779 _work[i][col] = _work[_work_rows-1][col];
00780 }
00781 }
00782 _work_rows--;
00783 }
00784 }
00785 }
00786
00787
00788
00789
00790
00791
00792
00793 INT SYSTEM_OF_EQUATIONS::Is_Simple_Redundant(const mINT32* row1,
00794 const mINT32* row2,
00795 INT64 row1c,
00796 INT64 row2c,
00797 INT min_var,
00798 INT cols)
00799 {
00800 BOOL has_multiple = FALSE;
00801 INT32 mult_n=1, mult_d=1;
00802
00803 for (INT col = min_var; col < cols; col++) {
00804 if (row1[col] == 0) {
00805 if(row2[col] != 0) return(0);
00806 }
00807 else if (row2[col] == 0) {
00808 if(row1[col] != 0) return(0);
00809 }
00810 else if (has_multiple) {
00811 if ((INT64) mult_n * row2[col] != (INT64) mult_d*row1[col]) return(0);
00812 }
00813 else {
00814 has_multiple = TRUE;
00815 mult_n = row1[col];
00816 mult_d = row2[col];
00817 if ((mult_n < 0) != (mult_d < 0)) return(0);
00818 }
00819 }
00820
00821 if (abs(row1c) > INT32_MAX) return(0);
00822 if (abs(row2c) > INT32_MAX) return(0);
00823
00824
00825
00826 if (mult_n == mult_d) {
00827 if (row1c <= row2c) {
00828 return 2;
00829 } else {
00830 return 1;
00831 }
00832 } else {
00833 if (mult_d > 0 && mult_d*row1c <= mult_n*row2c
00834 || mult_d < 0 && mult_d*row1c >= mult_n*row2c) {
00835 return 2;
00836 } else {
00837 return 1;
00838 }
00839 }
00840 }
00841
00842
00843
00844
00845
00846
00847
00848
00849 INT SYSTEM_OF_EQUATIONS::Simple_Redundant(const mINT32* row1,
00850 const mINT32* row2,
00851 INT64 row1c,
00852 INT64 row2c,
00853 INT min_var,
00854 INT cols)
00855 {
00856 BOOL has_multiple = FALSE;
00857 INT32 mult_n=1, mult_d=1;
00858
00859 for (INT col = min_var; col < cols; col++) {
00860 if (row1[col] == 0) {
00861 if(row2[col] != 0) return(0);
00862 }
00863 else if (row2[col] == 0) {
00864 if(row1[col] != 0) return(0);
00865 }
00866 else if (has_multiple) {
00867 if ((INT64) mult_n * row2[col] != (INT64) mult_d*row1[col]) return(0);
00868 }
00869 else {
00870 has_multiple = TRUE;
00871 mult_n = row1[col];
00872 mult_d = row2[col];
00873 if ((mult_n < 0) != (mult_d < 0)) return(0);
00874 }
00875 }
00876
00877 if (abs(row1c) > INT32_MAX) return(0);
00878 if (abs(row2c) > INT32_MAX) return(0);
00879
00880
00881 if (mult_n == mult_d) {
00882 if (row1c < row2c) {
00883 return 2;
00884 } else if (row2c < row1c) {
00885 return 1;
00886 } else
00887 return 3;
00888
00889 } else {
00890 if (mult_d*row1c < mult_n*row2c) {
00891 return 2;
00892 } else if (mult_d*row1c > mult_n*row2c) {
00893 return 1;
00894 } else
00895 return 3;
00896
00897 }
00898 }
00899
00900
00901
00902
00903 BOOL SYSTEM_OF_EQUATIONS::Copy_To_Work(const INT32 from, const INT32 to)
00904 {
00905 if (_work_rows + (to-from+1) > SOE_MAX_WORK_ROWS) return(FALSE);
00906 if (_work_rows ==0) {
00907 if (_vars > SOE_MAX_WORK_COLS) return(FALSE);
00908 _work_cols = _vars;
00909 } else {
00910 FmtAssert(_vars==_work_cols,("Inconsistency in Copy_To_Work"));
00911 }
00912 INT32 initial_work_rows = _work_rows;
00913
00914 INT32 i;
00915 for (i=from; i<= to; i++ ) {
00916 for (INT32 j=0; j<_work_cols; j++) {
00917 _work[_work_rows][j] = _Ale(i,j);
00918 }
00919 _work_rows++;
00920 }
00921 _work_rows = initial_work_rows;
00922 for (i=from; i <= to; i++) {
00923 _work_const[_work_rows++] = _ble[i];
00924 }
00925 return(TRUE);
00926 }
00927
00928
00929
00930 BOOL SYSTEM_OF_EQUATIONS::Copy_Inverse_To_Work(const INT32 i)
00931 {
00932 if (_work_rows + 1 > SOE_MAX_WORK_ROWS) return(FALSE);
00933 if (_work_rows ==0) {
00934 if (_vars > SOE_MAX_WORK_COLS) return(FALSE);
00935 _work_cols = _vars;
00936 } else {
00937 FmtAssert(_vars==_work_cols,("Inconsistency in Copy_Inverse_To_Work"));
00938 }
00939
00940 for (INT32 j=0; j<_vars; j++) {
00941 _work[_work_rows][j] = -_Ale(i,j);
00942 }
00943 _work_const[_work_rows] = -_ble[i]-1;
00944 _work_rows++;
00945 return(TRUE);
00946 }
00947
00948
00949
00950 BOOL SYSTEM_OF_EQUATIONS::Copy_To_Work_Eq()
00951 {
00952 if (_eqns_eq > SOE_MAX_WORK_ROWS_EQ) return(FALSE);
00953 if (_work_rows ==0) {
00954 if (_vars > SOE_MAX_WORK_COLS) return(FALSE);
00955 _work_cols = _vars;
00956 } else {
00957 FmtAssert(_vars==_work_cols,("Inconsistency in Copy_Inverse_To_Work"));
00958 }
00959 _work_rows_eq = _eqns_eq;
00960
00961 for (INT32 i=0; i< _eqns_eq; i++ ) {
00962 _work_const_eq[i] = _beq[i];
00963 for (INT32 j=0; j<_work_cols; j++) {
00964 _work_eq[i][j] = _Aeq(i,j);
00965 }
00966 }
00967 return(TRUE);
00968 }
00969
00970
00971
00972
00973 BOOL SYSTEM_OF_EQUATIONS::Is_Consistent_Work()
00974 {
00975 INT debug = 0;
00976 if (Get_Trace(TP_LNOPT,TT_LNO_DEP2)) {
00977 debug = 2;
00978 }
00979
00980 SVPC_RESULT result = SVPC();
00981 if (result == SVPC_CONSISTENT) {
00982 if (debug >= 2) fprintf(TFile,"SVPC returns consistent \n");
00983 return (TRUE);
00984 } else if (result == SVPC_INCONSISTENT) {
00985 if (debug >= 2) fprintf(TFile,"SVPC returns inconsistent \n");
00986 return(FALSE);
00987 }
00988
00989 ACY_RESULT acy_result = Acyclic_Test();
00990 if (acy_result == ACY_CONSISTENT) {
00991 if (debug >= 2) fprintf(TFile,"acyclic returns consistent \n");
00992 return (TRUE);
00993 } else if (acy_result == ACY_INCONSISTENT) {
00994 if (debug >= 2) fprintf(TFile,"acyclic returns inconsistent \n");
00995 return(FALSE);
00996 }
00997
00998 Gcd_Normalize();
00999
01000 BOOL proved_inconsistent;
01001 for (INT32 i=0; i<_work_cols-1; i++) {
01002 if (!Project(i,&proved_inconsistent,i)) {
01003 if (debug >= 2) fprintf(TFile,"fourier returns consistent \n");
01004 return(TRUE);
01005 } else if (proved_inconsistent) {
01006 if (debug >= 2) fprintf(TFile,"fourier returns inconsistent \n");
01007 return(FALSE);
01008 }
01009 }
01010 BOOL four_result = One_Var_Consistent(_work_cols-1,0,_work_rows-1);
01011 if (debug >= 2) {
01012 if (four_result) fprintf(TFile,"fourier returns consistent \n");
01013 else fprintf(TFile,"fourier returns inconsistent \n");
01014 }
01015 return four_result;
01016 }
01017
01018
01019 void SYSTEM_OF_EQUATIONS::Gcd_Normalize()
01020 {
01021
01022 INT32 g = 0;
01023 for (INT i=0; i<_work_rows; i++) {
01024 INT j=0;
01025 g = 0;
01026
01027 while (j<_work_cols && !_work[i][j]) j++;
01028 if (j<_work_cols) g = abs(_work[i][j]);
01029
01030 for (j=j+1; j<_work_cols; j++) {
01031 g = Gcd(g,abs(_work[i][j]));
01032 }
01033
01034 if (g && g != 1) {
01035 for (INT j=0; j<_work_cols; j++) {
01036 _work[i][j] = _work[i][j] / g;
01037 }
01038 if (_work_const[i] > 0 || ((_work_const[i] % g) == 0)) {
01039 _work_const[i] = _work_const[i] / g;
01040 } else {
01041 _work_const[i] = _work_const[i] / g -1;
01042 }
01043 }
01044 }
01045 }
01046
01047
01048
01049
01050 SVPC_RESULT SYSTEM_OF_EQUATIONS::SVPC()
01051 {
01052 BOOL applicable = TRUE;
01053
01054 INT32 i;
01055 for (i=0; i<_work_cols; i++) {
01056 _lower_bound[i].Set_Neg_Infinite();
01057 _upper_bound[i].Set_Infinite();
01058 }
01059
01060 for (i=0; i<_work_rows; i++) {
01061 INT32 num_vars = 0, var_pos=0;
01062 BOOL applicable_i = TRUE;
01063 for (INT32 j=0; j<_work_cols; j++) {
01064 if (_work[i][j] != 0) {
01065 if (num_vars) {
01066 applicable = FALSE;
01067 applicable_i = FALSE;
01068 }
01069 num_vars = 1;
01070 var_pos = j;
01071 }
01072 }
01073 if (num_vars == 0) {
01074 if (_work_const[i] < 0) {
01075 return(SVPC_INCONSISTENT);
01076 }
01077 } else if (applicable_i && !One_Var_Consistent(var_pos,i,i)) {
01078 return(SVPC_INCONSISTENT);
01079 }
01080 _is_svpc[i] = applicable_i;
01081 }
01082 if (!applicable) {
01083 return(SVPC_INAPPLICABLE);
01084 } else {
01085 return(SVPC_CONSISTENT);
01086 }
01087 }
01088
01089
01090
01091
01092
01093 BOOL SYSTEM_OF_EQUATIONS::One_Var_Consistent(INT32 var, INT32 from, INT32 to)
01094 {
01095 #ifdef KEY
01096
01097
01098
01099 if (! Allow_wrap_around_opt ) return (TRUE);
01100 #endif
01101 for (INT32 i=from; i<=to; i++) {
01102 if ((_work_const[i] >= (INT32_MAX-1)) || (_work_const[i]<=(INT32_MIN+1))) {
01103 return(TRUE);
01104 }
01105 SVPC_Set_Bound(i,var);
01106 if (_lower_bound[var] > _upper_bound[var]) {
01107 return(FALSE);
01108 }
01109 }
01110 return(TRUE);
01111 }
01112
01113
01114
01115
01116 void SYSTEM_OF_EQUATIONS::SVPC_Set_Bound(INT32 i, INT32 var)
01117 {
01118 INT32 tmp;
01119 if (_work[i][var] > 0) {
01120
01121
01122 if ((_work_const[i] >= 0) || (_work_const[i] % _work[i][var] == 0)) {
01123 tmp = _work_const[i] / _work[i][var];
01124 } else {
01125 tmp = -(-_work_const[i] / _work[i][var]) -1;
01126 }
01127 if (tmp < _upper_bound[var]) _upper_bound[var] = tmp;
01128
01129 } else if (_work[i][var] < 0) {
01130
01131 if ((_work_const[i] >= 0) || (_work_const[i] % _work[i][var] == 0)) {
01132 tmp = -(_work_const[i] / (-_work[i][var]));
01133 } else {
01134 tmp = (-_work_const[i] / -_work[i][var]) + 1;
01135 }
01136 if (tmp > _lower_bound[var]) _lower_bound[var] = tmp;
01137 } else {
01138 if (_work_const[i] < 0) {
01139 _lower_bound[var] = 1;
01140 _upper_bound[var] = 0;
01141 }
01142 }
01143 }
01144
01145
01146
01147
01148
01149
01150 ACY_RESULT SYSTEM_OF_EQUATIONS::Acyclic_Test()
01151 {
01152 INT sign=0;
01153 BOOL inconsistent;
01154
01155 BOOL *var_substituted = CXX_NEW_ARRAY(BOOL,_work_cols,_pool);
01156
01157 for (INT i=0; i<_work_cols; i++) {
01158 var_substituted[i] = FALSE;
01159 }
01160
01161 BOOL subbed_one = TRUE;
01162 BOOL failed_one = TRUE;
01163 while (subbed_one && failed_one) {
01164 subbed_one = FALSE;
01165 failed_one = FALSE;
01166 for (INT i=0; i<_work_cols; i++) {
01167 if (!var_substituted[i]) {
01168 if (Var_Leaf(i,&sign)) {
01169 var_substituted[i] = TRUE;
01170 if (sign > 0) {
01171 subbed_one = TRUE;
01172 Acy_Set_Var(i,_lower_bound[i],&inconsistent);
01173 if (inconsistent) {
01174 CXX_DELETE_ARRAY(var_substituted,_pool);
01175 return(ACY_INCONSISTENT);
01176 }
01177 } else if (sign < 0) {
01178 subbed_one = TRUE;
01179 Acy_Set_Var(i,_upper_bound[i],&inconsistent);
01180 if (inconsistent) {
01181 CXX_DELETE_ARRAY(var_substituted,_pool);
01182 return(ACY_INCONSISTENT);
01183 }
01184 }
01185 } else {
01186 failed_one = TRUE;
01187 }
01188 }
01189 }
01190 }
01191 if (failed_one) {
01192 return(ACY_INAPPLICABLE);
01193 }
01194 return (ACY_CONSISTENT);
01195 }
01196
01197
01198
01199
01200
01201
01202 INT SYSTEM_OF_EQUATIONS::Var_Leaf(INT i, INT *sign)
01203 {
01204 INT s=0;
01205 for (INT row=0; row<_work_rows; row++) {
01206 if (!_is_svpc[row]) {
01207 if (_work[row][i] > 0) {
01208 if (s == -1) return 0;
01209 s = 1;
01210 } else if (_work[row][i] < 0) {
01211 if (s == 1) return 0;
01212 s = -1;
01213 }
01214 }
01215 }
01216 *sign = s;
01217 return(1);
01218 }
01219
01220
01221
01222
01223
01224 void SYSTEM_OF_EQUATIONS::Acy_Set_Var(INT i,INT32_INFIN val,BOOL *inconsistent)
01225 {
01226 BOOL is_infin = (val.Is_Infinite() || val.Is_Neg_Infinite());
01227 INT v;
01228 if (!is_infin) {
01229 v = val.Value();
01230 }
01231
01232 for (INT row=0; row<_work_rows; row++) {
01233 if (!_is_svpc[row]) {
01234 if (_work[row][i]) {
01235 if (is_infin) {
01236 _work_const[row] = 0;
01237 for (INT j=0; j<_work_cols; j++) {
01238 _work[row][j] = 0;
01239 }
01240 _is_svpc[row] = TRUE;
01241 } else {
01242 if (_work[row][i] == 1) {
01243 _work_const[row] -= v;
01244 } else if (_work[row][i] == -1) {
01245 _work_const[row] += v;
01246 } else {
01247 _work_const[row] -= _work[row][i]*v;
01248 }
01249 _work[row][i] = 0;
01250
01251
01252 INT32 num_vars=0, var_pos=0;
01253 for (INT j=0; j<_work_cols && (num_vars <= 1); j++) {
01254 if (_work[row][j] != 0) {
01255 num_vars++;
01256 var_pos = j;
01257 }
01258 }
01259 if (num_vars == 1) {
01260 if (!One_Var_Consistent(var_pos,row,row)) {
01261 *inconsistent = TRUE;
01262 return;
01263 }
01264 _is_svpc[row] = TRUE;
01265 }
01266 }
01267 }
01268 }
01269 }
01270 *inconsistent = FALSE;
01271 }
01272
01273
01274
01275
01276
01277 BOOL SYSTEM_OF_EQUATIONS::Sub_Last_Equal(BOOL *proved_inconsistent)
01278 {
01279 INT32 eqnum = _work_rows_eq - 1;
01280
01281
01282 INT32 i;
01283 for (i=0; i<_work_cols && _work_eq[eqnum][i] == 0; i++);
01284 if (i == _work_cols) {
01285 if (_work_const_eq[eqnum] != 0) {
01286 *proved_inconsistent = TRUE;
01287 }
01288 _work_rows_eq--;
01289 return(TRUE);
01290 }
01291
01292
01293
01294 if (abs(_work_eq[eqnum][i]) == 1) {
01295 if (!Sub_Last_Equal_Unary(i,i)) return(FALSE);;
01296 _work_rows_eq--;
01297 return(TRUE);
01298 }
01299
01300
01301 INT32 smallest_var = Normalize_Eq_and_Find_Smallest
01302 (eqnum,i,proved_inconsistent);
01303 if (*proved_inconsistent) return(TRUE);
01304 if (abs(_work_eq[eqnum][smallest_var]) == 1) {
01305 if (!Sub_Last_Equal_Unary(smallest_var,i)) return(FALSE);
01306 _work_rows_eq--;
01307 return(TRUE);
01308 }
01309
01310
01311 Add_Work_Var();
01312 INT32 m = abs(_work_eq[eqnum][smallest_var]) + 1;
01313 _work_rows_eq++; eqnum++;
01314
01315 _work_eq[eqnum][_work_cols-1] = m;
01316 for (i=0; i<_work_cols-1; i++) {
01317 _work_eq[eqnum][i] = -Mod_Hat(_work_eq[eqnum-1][i],m);
01318 }
01319 _work_const_eq[eqnum] = -Mod_Hat(_work_const_eq[eqnum-1],m);
01320 return(TRUE);
01321 }
01322
01323
01324
01325
01326
01327 BOOL SYSTEM_OF_EQUATIONS::Sub_Last_Equal_Unary(const INT32 i,const INT32 minvar)
01328 {
01329 INT32 eqnum = _work_rows_eq - 1;
01330 if (_work_eq[eqnum][i] == -1) {
01331 for (INT32 j=minvar; j<_work_cols; j++) {
01332 _work_eq[eqnum][j] = -_work_eq[eqnum][j];
01333 }
01334 _work_const_eq[eqnum] = -_work_const_eq[eqnum];
01335 }
01336
01337
01338 for (INT32 eq=0; eq<eqnum; eq++) {
01339 INT64 mult = (INT64) _work_eq[eq][i];
01340
01341 if (mult == 0) {
01342 } else if (mult == 1) {
01343 for (INT32 j=minvar; j<_work_cols; j++) {
01344 INT64 tmp = (INT64) _work_eq[eq][j] - (INT64) _work_eq[eqnum][j];
01345 if (abs(tmp) > INT32_MAX) return(FALSE);
01346 _work_eq[eq][j] = (INT32) tmp;
01347 }
01348 _work_const_eq[eq] -= _work_const_eq[eqnum];
01349 } else if (mult == -1) {
01350 for (INT32 j=minvar; j<_work_cols; j++) {
01351 INT64 tmp = (INT64) _work_eq[eq][j] + (INT64) _work_eq[eqnum][j];
01352 if (abs(tmp) > INT32_MAX) return(FALSE);
01353 _work_eq[eq][j] = (INT32) tmp;
01354 }
01355 _work_const_eq[eq] += _work_const_eq[eqnum];
01356 } else {
01357 for (INT32 j=minvar; j<_work_cols; j++) {
01358 INT64 tmp = (INT64) _work_eq[eq][j] - mult*_work_eq[eqnum][j];
01359 if (abs(tmp) > INT32_MAX) return(FALSE);
01360 _work_eq[eq][j] = (INT32) tmp;
01361 }
01362 _work_const_eq[eq] -= mult*_work_const_eq[eqnum];
01363 }
01364 _work_eq[eq][i] = 0;
01365 }
01366
01367
01368 for (INT32 le=0; le<_work_rows; le++) {
01369 INT32 mult = _work[le][i];
01370 if (mult == 0) {
01371 } else if (mult == 1) {
01372 for (INT32 j=minvar; j<_work_cols; j++) {
01373 INT64 tmp = (INT64) _work[le][j] - (INT64) _work_eq[eqnum][j];
01374 if (abs(tmp) > INT32_MAX) return(FALSE);
01375 _work[le][j] = (INT32) tmp;
01376 }
01377 _work_const[le] -= _work_const_eq[eqnum];
01378 } else if (mult == -1) {
01379 for (INT32 j=minvar; j<_work_cols; j++) {
01380 INT64 tmp = (INT64) _work[le][j] + (INT64) _work_eq[eqnum][j];
01381 if (abs(tmp) > INT32_MAX) return(FALSE);
01382 _work[le][j] = (INT32) tmp;
01383 }
01384 _work_const[le] += _work_const_eq[eqnum];
01385 } else {
01386 for (INT32 j=minvar; j<_work_cols; j++) {
01387 INT64 tmp = (INT64) _work[le][j] - mult*_work_eq[eqnum][j];
01388 if (abs(tmp) > INT32_MAX) return(FALSE);
01389 _work[le][j] = (INT32) tmp;
01390 }
01391 _work_const[le] -= mult*_work_const_eq[eqnum];
01392 }
01393 _work[le][i] = 0;
01394 }
01395 return(TRUE);
01396 }
01397
01398
01399
01400
01401
01402 INT32 SYSTEM_OF_EQUATIONS::Normalize_Eq_and_Find_Smallest
01403 (INT32 eqnum,INT32 minvar,BOOL *proved_inconsistent)
01404 {
01405 INT32 g = abs(_work_eq[eqnum][minvar]);
01406 INT32 smallest = g;
01407 INT32 smallest_pos = minvar;
01408
01409 Is_True(g != 0,
01410 ("Bad minvar for SYSTEM_OF_EQUATIONS::Normalize_Eq_and_Find_Smallest"));
01411
01412
01413 INT32 i;
01414 for (i=minvar+1; i<_work_cols; i++) {
01415 INT32 tmp = abs(_work_eq[eqnum][i]);
01416 if (tmp != 0) {
01417 g = Gcd(g,tmp);
01418 if (tmp < smallest) {
01419 smallest = tmp;
01420 smallest_pos = i;
01421 }
01422 }
01423 }
01424
01425 if (abs(_work_const_eq[eqnum]) % g != 0) {
01426 *proved_inconsistent = TRUE;
01427 return(-1);
01428 }
01429
01430
01431 _work_const_eq[eqnum] /= g;
01432 for (i=minvar; i<_work_cols; i++) {
01433 _work_eq[eqnum][i] /= g;
01434 }
01435 return(smallest_pos);
01436 }
01437
01438 void SYSTEM_OF_EQUATIONS::Take_Gcds()
01439 {
01440 INT i;
01441 for (i = 0; i < _eqns_le; i++) {
01442 INT64 g = _Ale(i,0);
01443 INT j;
01444 for (j = 1; j < _vars; j++)
01445 g = Gcd(g, (INT64)_Ale(i,j));
01446 if (g == 0)
01447 continue;
01448 FmtAssert(g>0, ("Take_Gcds(): impossible gcd %lld", g));
01449 for (j = 0; j < _vars; j++)
01450 _Ale(i,j) /= (INT32)g;
01451 if (_ble[i] >= 0)
01452 _ble[i] = _ble[i]/(INT32)g;
01453 else
01454 _ble[i] = -((-_ble[i] + g - 1)/(INT32)g);
01455 }
01456
01457 for (i = 0; i < _eqns_eq; i++) {
01458 INT64 g = _beq[i];
01459 INT j;
01460 for (j = 0; j < _vars; j++)
01461 g = Gcd(g, (INT64)_Aeq(i,j));
01462 if (g == 0)
01463 continue;
01464 FmtAssert(g>0, ("Take_Gcds(): impossible gcd %lld", g));
01465 for (j = 0; j < _vars; j++)
01466 _Aeq(i,j) /= (INT32)g;
01467 _beq[i] /= (INT32)g;
01468 }
01469 }
01470
01471
01472 INT32 SYSTEM_OF_EQUATIONS::Mod_Hat(INT32 a, INT32 b)
01473 {
01474 INT32 num = 2*a+b;
01475 INT32 den = 2*b;
01476 INT32 floor;
01477 if (((num >= 0) && (den >0)) || ((num <= 0) && (den <0))) {
01478 floor = num/den;
01479 } else if ((num % den) == 0) {
01480 floor = num/den;
01481 } else {
01482 floor = num/den-1;
01483 }
01484 return(a-b*floor);
01485 }
01486
01487
01488
01489 BOOL SYSTEM_OF_EQUATIONS::Add_Work_Var()
01490 {
01491 if (_work_cols >= SOE_MAX_WORK_COLS) return(FALSE);
01492
01493 INT32 i;
01494 for (i=0; i<_work_rows; i++) {
01495 _work[i][_work_cols] = 0;
01496 }
01497 for (i=0; i<_work_rows_eq; i++) {
01498 _work_eq[i][_work_cols] = 0;
01499 }
01500 _work_cols++;
01501 return(TRUE);
01502 }
01503
01504 void SYSTEM_OF_EQUATIONS::Reset_To(INT32 nrows_le, INT32 nrows_eq, INT32 ncols)
01505 {
01506 INT32 nle = Num_Le_Constraints() - nrows_le;
01507 INT32 neq = Num_Eq_Constraints() - nrows_eq;
01508 INT32 nvr = Num_Vars() - ncols;
01509
01510 if (nle > 0) Remove_Last_Le(nle);
01511 else Is_True(nle == 0, ("Reset_To can't add Ale rows"));
01512
01513 if (neq > 0) Remove_Last_Eq(neq);
01514 else Is_True(neq == 0, ("Reset_To can't add Aeq rows"));
01515
01516 if (nvr > 0) Remove_Last_Vars(nvr);
01517 else Is_True(nvr == 0, ("Reset_To can't add variables"));
01518 }
01519
01520
01521 mINT32 SYSTEM_OF_EQUATIONS::_work[SOE_MAX_WORK_ROWS][SOE_MAX_WORK_COLS];
01522 mINT64 SYSTEM_OF_EQUATIONS::_work_const[SOE_MAX_WORK_ROWS];
01523 mINT32 SYSTEM_OF_EQUATIONS::_work_rows;
01524 mINT32 SYSTEM_OF_EQUATIONS::_work_cols;
01525 BOOL SYSTEM_OF_EQUATIONS::_is_redundant[SOE_MAX_WORK_ROWS];
01526 BOOL SYSTEM_OF_EQUATIONS::_is_svpc[SOE_MAX_WORK_ROWS];
01527 INT32_INFIN SYSTEM_OF_EQUATIONS::_lower_bound[SOE_MAX_WORK_COLS];
01528 INT32_INFIN SYSTEM_OF_EQUATIONS::_upper_bound[SOE_MAX_WORK_COLS];
01529 mINT32
01530 SYSTEM_OF_EQUATIONS::_work_eq[SOE_MAX_WORK_ROWS_EQ][SOE_MAX_WORK_COLS];
01531 mINT64 SYSTEM_OF_EQUATIONS::_work_const_eq[SOE_MAX_WORK_ROWS_EQ];
01532 mINT32 SYSTEM_OF_EQUATIONS::_work_rows_eq;
01533
01534 void SYSTEM_OF_EQUATIONS::Remove_Eq_Number(INT k)
01535 {
01536 for (INT i = k+1; i < _eqns_eq; i++) {
01537 for (INT j = 0; j < _vars; j++)
01538 Aeq()(i-1,j) = Aeq()(i,j);
01539 Beq()[i-1] = Beq()[i];
01540 }
01541 _eqns_eq--;
01542 }
01543
01544 void SYSTEM_OF_EQUATIONS::Remove_Le_Number(INT k)
01545 {
01546 for (INT i = k+1; i < _eqns_le; i++) {
01547 for (INT j = 0; j < _vars; j++)
01548 Ale()(i-1,j) = Ale()(i,j);
01549 Ble()[i-1] = Ble()[i];
01550 }
01551 _eqns_eq--;
01552 }
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564 INT
01565 SYSTEM_OF_EQUATIONS::Change_Base(const INT32 dim, const INT32 pos, MEM_POOL *pool)
01566 {
01567
01568 INT pivot_row = -1;
01569 INT pivot_column = dim+pos;
01570
01571 INT32 i;
01572 for (i = 0; i < _eqns_eq; ++i) {
01573 if (_Aeq(i,pivot_column) != 0) {
01574 if (pivot_row < 0)
01575 pivot_row = i;
01576 else if (abs(_Aeq(i,pivot_column)) < abs(_Aeq(pivot_row,pivot_column)))
01577 pivot_row = i;
01578 }
01579 }
01580
01581
01582
01583 if (pivot_row < 0) return pivot_row;
01584
01585 INT64 *work = CXX_NEW_ARRAY(INT64, _vars, pool);
01586 INT64 pivot_value = _Aeq(pivot_row,pivot_column);
01587
01588
01589 for (i = 0; i < _eqns_eq; ++i) {
01590 if (i!=pivot_row && _Aeq(i,pivot_column)!=0) {
01591 INT32 k;
01592 for (k = 0; k <_vars; ++k) {
01593 work[k] = - pivot_value*_Aeq(i,k)
01594 + _Aeq(i,pivot_column)*_Aeq(pivot_row,k);
01595 }
01596
01597 _beq[i] = - pivot_value*_beq[i] + _Aeq(i,pivot_column)*_beq[pivot_row];
01598
01599 if (abs(_beq[i]) > INT32_MAX) {
01600 CXX_DELETE(work, pool);
01601 return -1;
01602 }
01603
01604 INT32 g = abs(_beq[i]);
01605
01606 for (k = 0; k <_vars; ++k) {
01607 if (abs(work[k] <= INT32_MAX)) {
01608 _Aeq(i,k) = work[k];
01609 g = Gcd(g,abs(work[k]));
01610 } else {
01611 CXX_DELETE(work, pool);
01612 return -1;
01613 }
01614 }
01615 if (g>1) {
01616 for (INT32 k = 0; k < _vars; ++k)
01617 _Aeq(i,k) = _Aeq(i,k)/g;
01618 _beq[i] = _beq[i]/g;
01619 }
01620 }
01621 }
01622
01623
01624 for ( i = 0; i < _eqns_le; ++i) {
01625 if (_Ale(i,pivot_column)!=0) {
01626 INT32 k;
01627 for (k = 0; k <_vars; ++k) {
01628 if (pivot_value < 0) {
01629 work[k] = - pivot_value*_Ale(i,k)
01630 + _Ale(i,pivot_column)*_Aeq(pivot_row,k);
01631 } else {
01632 work[k] = pivot_value*_Ale(i,k)
01633 - _Ale(i,pivot_column)*_Aeq(pivot_row,k);
01634 }
01635 }
01636 if (pivot_value < 0) {
01637 _ble[i] = - pivot_value*_ble[i] + _Ale(i,pivot_column)*_beq[pivot_row];
01638 } else {
01639 _ble[i] = pivot_value*_ble[i] - _Ale(i,pivot_column)*_beq[pivot_row];
01640 }
01641
01642 if (abs(_ble[i]) > INT32_MAX) {
01643 CXX_DELETE(work, pool);
01644 return FALSE;
01645 }
01646
01647 INT32 g = abs(_ble[i]);
01648
01649 for (k = 0; k < _vars; ++k) {
01650 if (abs(work[k] <= INT32_MAX)) {
01651 _Ale(i,k) = work[k];
01652 g = Gcd(g, abs(work[k]));
01653 } else {
01654 CXX_DELETE(work, pool);
01655 return -1;
01656 }
01657 }
01658 if (g>1) {
01659 for (INT32 k = 0; k < _vars; ++k)
01660 _Ale(i,k) = _Ale(i,k)/g;
01661 _ble[i] = _ble[i]/g;
01662 }
01663 }
01664 }
01665
01666 CXX_DELETE(work,pool);
01667 return pivot_row;
01668
01669 }
01670
01671
01672
01673
01674
01675
01676
01677
01678 INT SYSTEM_OF_EQUATIONS::Mark_Simple_Redundant(BOOL *is_redundant)
01679 {
01680 INT counter=0;
01681 static INT16 last_non_zero[SOE_MAX_WORK_ROWS];
01682
01683
01684
01685 INT i;
01686 for (i=0; i<_work_rows; i++) {
01687 is_redundant[i] = FALSE;
01688 INT j = _work_cols - 1;
01689 while ((j >= 0) && (_work[i][j] == 0)) j--;
01690 last_non_zero[i] = j;
01691 }
01692
01693
01694 for (i=0; i<_work_rows; i++) {
01695 if (!is_redundant[i]) {
01696 for (INT32 j=i+1; j<_work_rows; j++) {
01697 if (!is_redundant[j] && (last_non_zero[i] == last_non_zero[j])) {
01698 INT redun=Is_Simple_Redundant(&_work[i][0], &_work[j][0],
01699 _work_const[i], _work_const[j],
01700 0, _work_cols);
01701 if (redun==1) {
01702 is_redundant[i] = TRUE;
01703 counter++;
01704 } else if (redun==2) {
01705 is_redundant[j] = TRUE;
01706 counter++;
01707 }
01708 }
01709 }
01710 }
01711 }
01712
01713 return counter++;
01714 }
01715
01716
01717
01718
01719
01720
01721
01722 INT SYSTEM_OF_EQUATIONS::Mark_New_Redundant(BOOL *is_redundant)
01723 {
01724 BOOL proved_inconsistent;
01725 INT counter = 0;
01726
01727 if (_eqns_le < 1) return 0;
01728
01729 for (INT32 i=0; i<_eqns_le; i++) {
01730 _work_rows = 0;
01731
01732 INT32 j;
01733 for (j=0; j<= i-1; j++) {
01734 if (!is_redundant[j]) {
01735 if (!Copy_To_Work(j,j)) return counter;
01736 }
01737 }
01738
01739 for (j =i+1; j<_eqns_le; j++) {
01740 if (!is_redundant[j]) {
01741 if (!Copy_To_Work(j,j)) return counter;
01742 }
01743 }
01744
01745 if (!Copy_Inverse_To_Work(i)) return counter;
01746 if (!Sub_In_Equal(&proved_inconsistent)) return counter;
01747 if (proved_inconsistent || !Is_Consistent_Work()) {
01748 is_redundant[i] = TRUE;
01749 counter++;
01750 }
01751 }
01752
01753 return counter;
01754 }
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769 BOOL SYSTEM_OF_EQUATIONS::Prove_Redundant(const INT set, const INT dim)
01770 {
01771
01772 Is_True(_eqns_le == 4*dim, ("The number of constraints does not match that of dimensions"));
01773 INT set1= (set) ? 0 : 1;
01774
01775 for (INT32 i = 0; i<dim; ++i) {
01776 _work_rows=0;
01777
01778
01779 INT32 j;
01780 for (j = 0; j<dim; ++j) {
01781 if (!Copy_To_Work(4*j+2*set1,4*j+2*set1)||
01782 !Copy_To_Work(4*j+2*set1+1,4*j+2*set1+1))
01783 return FALSE;
01784 }
01785
01786
01787 if (!Copy_Inverse_To_Work(4*i+2*set)) return FALSE;
01788 if (Is_Consistent_Work()) return FALSE;
01789
01790 _work_rows=0;
01791
01792
01793 for (j = 0; j<dim; ++j) {
01794 if (!Copy_To_Work(4*j+2*set1,4*j+2*set1)||
01795 !Copy_To_Work(4*j+2*set1+1,4*j+2*set1+1))
01796 return FALSE;
01797 }
01798
01799
01800 if (!Copy_Inverse_To_Work(4*i+2*set+1)) return FALSE;
01801 if (Is_Consistent_Work()) return FALSE;
01802 }
01803
01804 return TRUE;
01805
01806 }