PIPS
sc_feasibility.c
Go to the documentation of this file.
1 /*
2 
3  $Id: sc_feasibility.c 1671 2019-06-26 19:14:11Z coelho $
4 
5  Copyright 1989-2016 MINES ParisTech
6 
7  This file is part of Linear/C3 Library.
8 
9  Linear/C3 Library is free software: you can redistribute it and/or modify it
10  under the terms of the GNU Lesser General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  any later version.
13 
14  Linear/C3 Library is distributed in the hope that it will be useful, but WITHOUT ANY
15  WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  FITNESS FOR A PARTICULAR PURPOSE.
17 
18  See the GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with Linear/C3 Library. If not, see <http://www.gnu.org/licenses/>.
22 
23 */
24 
25 /*
26  * This file provides functions to test the feasibility of a system of
27  * constraints.
28  *
29  * Arguments of these functions :
30  *
31  * - s or sc is the system of constraints.
32  * - ofl_ctrl is the way overflow errors are handled
33  * ofl_ctrl == NO_OFL_CTRL
34  * -> overflow errors are not handled
35  * ofl_ctrl == OFL_CTRL
36  * -> overflow errors are handled in the called function
37  * ofl_ctrl == FWD_OFL_CTRL
38  * -> overflow errors must be handled by the calling function
39  * - ofl_res is the result of the feasibility test when ofl_ctrl == OFL_CTRL
40  * and there is an overflow error.
41  * - integer_p (low_level function only) is a bool :
42  * integer_p == true to test if there exists at least one integer point
43  * in the convex polyhedron defined by the system of constraints.
44  * integer_p == false to test if there exists at least one rational point
45  * in the convex polyhedron defined by the system of constraints.
46  * (This has an impact only upon Fourier-Motzkin feasibility test).
47  *
48  * Last modified by Beatrice Creusillet, 13/12/94.
49  * Pls see dn_implementation.ps for recent changes.
50  */
51 
52 #ifdef HAVE_CONFIG_H
53  #include "config.h"
54 #endif
55 
56 #include <stdlib.h>
57 #include <string.h>
58 #include <stdio.h>
59 #include "linear_assert.h"
60 
61 #include "boolean.h"
62 #include "arithmetique.h"
63 #include "vecteur.h"
64 #include "contrainte.h"
65 #include "sc.h"
66 #include "sc-private.h"
67 
68 #ifdef FILTERING
69 
70 #include <signal.h>
71 
72 #define EXCEPTION_PRINT_LINEAR_SIMPLEX true
73 #define EXCEPTION_PRINT_FM true
74 #define EXCEPTION_PRINT_JANUS true
75 
76 #define FILTERING_TIMEOUT_FM filtering_timeout_FM
77 #define FILTERING_TIMEOUT_LINEAR_SIMPLEX filtering_timeout_S
78 #define FILTERING_TIMEOUT_JANUS filtering_timeout_J
79 
80 #define FILTERING_DIMENSION_FEASIBILITY filtering_dimension_feasibility
81 #define FILTERING_NUMBER_CONSTRAINTS_FEASIBILITY filtering_number_constraints_feasibility
82 #define FILTERING_DENSITY_FEASIBILITY filtering_density_feasibility
83 #define FILTERING_MAGNITUDE_FEASIBILITY (Value) filtering_magnitude_feasibility
84 
85 #endif // FILTERING
86 
87 #define SWITCH_HEURISTIC_FLAG sc_switch_heuristic_flag
88 
89 static int feasibility_sc_counter = 0;
90 
91 bool FM_timeout = false;
92 bool J_timeout = false;
93 bool S_timeout = false;
94 
96 
97 /*
98  * INTERFACES
99  */
100 
101 bool
102 sc_rational_feasibility_ofl_ctrl(sc, ofl_ctrl, ofl_res)
103 Psysteme sc;
104 int ofl_ctrl;
105 bool ofl_res;
106 {
107  return sc_feasibility_ofl_ctrl(sc, false, ofl_ctrl, ofl_res);
108 }
109 
110 bool
111 sc_integer_feasibility_ofl_ctrl(sc,ofl_ctrl, ofl_res)
112 Psysteme sc;
113 int ofl_ctrl;
114 bool ofl_res;
115 {
116  return sc_feasibility_ofl_ctrl(sc, true, ofl_ctrl, ofl_res);
117 }
118 
119 /*
120  * LOW LEVEL FUNCTIONS
121  */
122 
123 #ifdef FILTERING
124 
125 static void
126 filtering_catch_alarm_FM (int sig)
127 {
128  alarm(0);
129  FM_timeout = true;
130 }
131 static void
132 filtering_catch_alarm_J (int sig)
133 {
134  alarm(0);
135  J_timeout = true;
136 }
137 static void
138 filtering_catch_alarm_S (int sig)
139 {
140  alarm(0);
141  S_timeout = true;
142 }
143 #endif
144 
145 /* just a test to improve the Simplex/FM decision.
146  * c is a list of constraints, equalities or inequalities
147  * pc is the number of constraints in the list
148  * pv is the number of non-zero coefficients in the system
149  * magnitude is the biggest coefficent in the system
150  * pc, pv and magnitude MUST be initialized. They are multiplied by weight.
151  *
152  * Modif:
153  * Become public, used by filters
154  */
155 void
157  Pcontrainte c,
158  int volatile *pc,
159  int volatile *pv,
160  Value *magnitude,
161  int weight)
162 {
163  Pvecteur v;
164  for(; c!=NULL; c=c->succ) {
165  v=c->vecteur;
166  if (v!=NULL) {
167  (*pc)+=weight;
168  for(; v!=NULL; v=v->succ)
169  if (var_of(v)!=TCST) {
170  (*pv) += weight;
171  if (value_gt(value_abs(val_of(v)),(*magnitude)))
172  value_assign(*magnitude,value_abs(val_of(v)));
173  }
174  }
175  }
176 }
177 
178 /* chose the next variable in base b for projection in system s.
179  * tries to avoid Fourier potential explosions when combining inequalities.
180  * - if there are equalities, chose the var with the min |coeff| (not null)
181  * - if there are only inequalities, chose the var that will generate the
182  * minimum number of constraints with pairwise combinations.
183  * - if ineq is true, consider variables even if no equalities.
184  *
185  * (c) FC 21 July 1995
186  */
187 static Variable
189 {
190  Pcontrainte c = sc_egalites(s);
191  Pvecteur v;
192  Variable var = NULL;
193  Value val;
194  int size = vect_size(b);
195 
196  ifscdebug(8)
197  {
198  fprintf(stderr, "[chose_variable_to_project_for_feasability] b/s:\n");
201  }
202 
203  if (size==1) return var_of(b);
204  assert(size>1);
205 
206  if (c)
207  {
208  /* find the lowest coeff
209  */
210  Variable minvar = TCST;
211  Value minval = VALUE_ZERO;
212 
213  for (; c; c=c->succ)
214  {
215  for (v = contrainte_vecteur(c); v; v=v->succ)
216  {
217  var = var_of(v);
218 
219  if (var!=TCST)
220  {
221  val = value_abs(val_of(v));
222  if ((value_notzero_p(minval) && value_lt(val,minval))
223  || value_zero_p(minval))
224  minval = val, minvar = var;
225 
226  if (value_one_p(minval)) return minvar;
227  }
228  }
229  }
230 
231  /* shouldn't find empty equalities ?? */
232  /* assert(minvar!=TCST); */
233  var = minvar;
234  }
235 
236  if (!var && ineq)
237  {
238  /* only inequalities, reduce the explosion
239  */
240  int i;
241  two_int_infop t = (two_int_infop) malloc(2*size*sizeof(int));
242  Pbase tmp;
243  int min_new;
244 
245  c = sc_inegalites(s);
246 
247  /* initialize t
248  */
249  for (i=0; i<size; i++) t[i][0]=0, t[i][1]=0;
250 
251  /* t[x][0 (resp. 1)] = number of negative (resp. positive) coeff
252  */
253  for (; c; c=c->succ)
254  {
255  for (v = contrainte_vecteur(c); v; v=v->succ)
256  {
257  var = var_of(v);
258  if (var!=TCST)
259  {
260  ifscdebug(9)
261  fprintf(stderr, "%s\n", default_variable_to_string(var));
262 
263  for (i=0, tmp=b; tmp && var_of(tmp)!=var;
264  i++, tmp=tmp->succ) (void) NULL;
265  assert(tmp);
266 
267  t[i][value_posz_p(val_of(v))]++;
268  }
269  }
270  }
271 
272  /* t[x][0] = number of combinations, i.e. new created constraints.
273  */
274  for (i=0; i<size; i++) t[i][0] *= t[i][1];
275 
276  for (tmp=b->succ, var=var_of(b), min_new=t[0][0], i=1;
277  min_new && i<size;
278  i++, tmp=tmp->succ) {
279  if (t[i][0]<min_new)
280  min_new = t[i][0], var=var_of(tmp);
281  }
282 
283  free(t);
284  }
285 
286  ifscdebug(8)
287  fprintf(stderr, "[chose_variable_to_project_for_feasability] "
288  "suggesting %s\n", default_variable_to_string(var));
289 
290  return var;
291 }
292 
293 /* project in s1 (which is modified)
294  * using equalities or both equalities and inequalities.
295 */
297 (Psysteme volatile * ps1, bool integer_p, bool use_eq_only, int ofl_ctrl)
298 {
299  Pbase b = base_copy(sc_base(*ps1));
300  Variable var;
301  bool faisable = true;
302 
303  while (b && faisable)
304  {
305  var = chose_variable_to_project_for_feasability(*ps1, b, !use_eq_only);
306 
307  /* if use_eq_only */
308  if (!var) break;
309 
310  vect_erase_var(&b, var);
311 
312  ifscdebug(8) {
313  // Guess the variable is printable as a string if you debug...
314  fprintf(stderr,
315  "[sc_fm_project_variables] system before %s projection:\n",
316  (char *) var);
317  sc_fprint(stderr, *ps1, default_variable_to_string);
318  }
319 
320  sc_projection_along_variable_ofl_ctrl(ps1, var, ofl_ctrl);
321 
322  ifscdebug(8)
323  {
324  fprintf(stderr,
325  "[sc_fm_project_variables] system after projection:\n");
326  sc_fprint(stderr, *ps1, default_variable_to_string);
327  }
328 
329  if (sc_empty_p(*ps1))
330  {
331  faisable = false;
332  break;
333  }
334 
335  if (integer_p) {
336  *ps1 = sc_normalize(*ps1);
337  if (SC_EMPTY_P(*ps1))
338  {
339  faisable = false;
340  break;
341  }
342  }
343  }
344  base_rm(b);
345  return faisable;
346 }
347 
348 #define LINEAR_SIMPLEX_PROJECT_EQ_METHOD 11
349 #define LINEAR_SIMPLEX_NO_PROJECT_EQ_METHOD 12
350 #define FM_METHOD 13
351 #define JANUS_METHOD 14
352 #define ALL_METHOD 15
353 
354 /* We can add other heuristic if we need in an easy way.
355  * Note: FM is not good for big sc, but good enough for small sc.
356  * Simplex build a tableau, so it's not good for small sc
357  */
358 
359 #define HEURISTIC1 1 /* Keep the old heuristic of FC */
360 #define HEURISTIC2 2 /* Replace Simplex by Janus in heuristic 1 */
361 #define HEURISTIC3 3 /* Only for experiment. Test successtively 3 methods to see the coherence */
362 #define HEURISTIC4 4 /* The best?: (Linear Simplex vs Janus) try to use the method that succeeded recently. If failed than turn to another. Rely on the fact that the sc are similar. [optional?] : If the 2 methods fail, then call FM. This can solve many sc, in fact. */
363 
364 static int method_used = 0; /* means LINEAR_SIMPLEX :-) */
365 
367 (Psysteme sc, int heuristic, bool int_p, int ofl_ctrl)
368 {
369  bool ok = true;
370  int method, n_ref_eq = 0, n_ref_in = 0;
371  /* Automatic variables read in a CATCH block need to be declared volatile as
372  * specified by the documentation*/
373  int volatile n_cont_in = 0;
374  int volatile n_cont_eq = 0;
375  Value magnitude;
376 
378 
379  /* We can put the size filters here! filtering timeout is integrated in the methods themself
380  * size filtering: dimension,number_constraints, density, magnitude */
381 
382 #ifdef FILTERING
383  /*Begin size filters*/
384 
385  if (true) {
386  int dimens; int nb_cont_eq = 0; int nb_ref_eq = 0; int nb_cont_in = 0; int nb_ref_in = 0;
387 
388  dimens = sc->dimension; value_assign(magnitude,VALUE_ZERO);
389  decision_data(sc_egalites(sc), &nb_cont_eq, &nb_ref_eq, &magnitude, 1);
390  decision_data(sc_inegalites(sc), &nb_cont_in, &nb_ref_in, &magnitude, 1);
391 
392  if ((FILTERING_DIMENSION_FEASIBILITY)&&(dimens>=FILTERING_DIMENSION_FEASIBILITY)) {
393  char *directory_name = "feasibility_dimension_filtering_SC_OUT";
395  }
396  if ((FILTERING_NUMBER_CONSTRAINTS_FEASIBILITY)&&((nb_cont_eq + nb_cont_in) >= FILTERING_NUMBER_CONSTRAINTS_FEASIBILITY)) {
397  char *directory_name = "feasibility_number_constraints_filtering_SC_OUT";
399  }
400  if ((FILTERING_DENSITY_FEASIBILITY)&&((nb_ref_eq + nb_ref_in) >= FILTERING_DENSITY_FEASIBILITY)) {
401  char *directory_name = "feasibility_density_filtering_SC_OUT";
403  }
404  if ((value_notzero_p(FILTERING_MAGNITUDE_FEASIBILITY))&&(value_gt(magnitude,FILTERING_MAGNITUDE_FEASIBILITY))) {
405  char *directory_name = "feasibility_magnitude_filtering_SC_OUT";
407  }
408  }
409 
410  /*End size filters*/
411 #endif
412  if (int_p) sc_gcd_normalize(sc);
413  switch(heuristic) {
414  case (HEURISTIC1):
415  {
416  method=0, n_cont_eq = 0, n_ref_eq = 0, n_cont_in = 0, n_ref_in = 0;
417  value_assign(magnitude,VALUE_ZERO);
418  decision_data(sc_egalites(sc), &n_cont_eq, &n_ref_eq, &magnitude, 1);
419  decision_data(sc_inegalites(sc), &n_cont_in, &n_ref_in, &magnitude, 1);
420  /* HEURISTIC1
421  * if nb_ineg >= 10 and nb_eg < 6 then use LSimplex (replace n eg by 2n ineg)
422  * if nb_ineg >= 10 and nb_eg >= 6 then project eg and use LSimplex
423  * if nb_ineg < 10 then use FM */
424 
425  if (n_cont_in >= 10) {
426  if (n_cont_eq >= 6) {method=LINEAR_SIMPLEX_PROJECT_EQ_METHOD;}
428  } else {
429  method = FM_METHOD;
430  }
431  break;
432  }
433  case (HEURISTIC2):
434  {
435  method=0, n_cont_eq = 0, n_ref_eq = 0, n_cont_in = 0, n_ref_in = 0;
436  value_assign(magnitude,VALUE_ZERO);
437  decision_data(sc_egalites(sc), &n_cont_eq, &n_ref_eq, &magnitude, 1);
438  decision_data(sc_inegalites(sc), &n_cont_in, &n_ref_in, &magnitude, 1);
439 
440  if (n_cont_in >= 10) {
441  method = JANUS_METHOD;
442  } else { method = FM_METHOD;}
443  break;
444  }
445  case (HEURISTIC3):
446  {
447  method=0, n_cont_eq = 0, n_ref_eq = 0, n_cont_in = 0, n_ref_in = 0;
448  value_assign(magnitude,VALUE_ZERO);
449  decision_data(sc_egalites(sc), &n_cont_eq, &n_ref_eq, &magnitude, 1);
450  decision_data(sc_inegalites(sc), &n_cont_in, &n_ref_in, &magnitude, 1);
451 
452  method = ALL_METHOD;
453  break;
454  }
455  case (HEURISTIC4):
456  {
457  method=0, n_cont_eq = 0, n_ref_eq = 0, n_cont_in = 0, n_ref_in = 0;
458  value_assign(magnitude,VALUE_ZERO);
459  decision_data(sc_egalites(sc), &n_cont_eq, &n_ref_eq, &magnitude, 1);
460  decision_data(sc_inegalites(sc), &n_cont_in, &n_ref_in, &magnitude, 1);
461 
463 
464  /* ifscdebug(5) {fprintf(stderr,"nb_exceptions af %d\n",linear_number_of_exception_thrown);}*/
465 
466  if (n_cont_in >= 10) {
467  if (method_used==JANUS_METHOD) {
468  method_used = 0;/*LINEAR_SIMPLEX*/
469  ifscdebug(5) {fprintf(stderr,"J failes so change to LS ...");}
470  if (n_cont_eq>=6) {
471  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,true,int_p,ofl_ctrl);
472  }else{
473  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,false,int_p,ofl_ctrl);
474  }
475  ifscdebug(5) {fprintf(stderr," ...Passed\n");}
477  } else {
479  ifscdebug(5) {fprintf(stderr,"LS failed so change to J ...");}
481  ifscdebug(5) {fprintf(stderr," ...Passed\n");}
483  }
484  /* ok = sc_fourier_motzkin_feasibility_ofl_ctrl_timeout_ctrl(sc,int_p,ofl_ctrl);*/
485  } else {
486  ifscdebug(5) {fprintf(stderr,"\nFM fail with small sc => bug??? ...");}
487  if (method_used == JANUS_METHOD) {
489  /*Janus*/
490  }else {
491  if (n_cont_eq>=6) {
492  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,true,int_p,ofl_ctrl);
493  }else{
494  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,false,int_p,ofl_ctrl);
495  }
496  }
497  ifscdebug(5) {fprintf(stderr," ...Passed\n");}
499  }
500  }
501  TRY {
502  if (n_cont_in >= 10) {
503  if (method_used == JANUS_METHOD) {
505  }else {
506  if (n_cont_eq>=6) {
507  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,true,int_p,ofl_ctrl);
508  }else{
509  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,false,int_p,ofl_ctrl);
510  }
511  }
512  }
513  // sc_fourier_motzkin does not (yet?) support GMP
514  else if (linear_use_gmp()) {
515  if (n_cont_eq >= 6) {
516  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc, true, int_p, ofl_ctrl);
517  }
518  else {
519  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc, false, int_p, ofl_ctrl);
520  }
521  } else {
522  /*FM*/
524  }
526  }/*of TRY*/
527 
528  break;
529  }
530 
531  default: /*use heuristic1*/
532  {
533  method=0, n_cont_eq = 0, n_ref_eq = 0, n_cont_in = 0, n_ref_in = 0;
534  value_assign(magnitude,VALUE_ZERO);
535  decision_data(sc_egalites(sc), &n_cont_eq, &n_ref_eq, &magnitude, 1);
536  decision_data(sc_inegalites(sc), &n_cont_in, &n_ref_in, &magnitude, 1);
537 
538  if (n_cont_in >= 10) {
539  if (n_cont_eq >= 6) {method=LINEAR_SIMPLEX_PROJECT_EQ_METHOD;}
541  } else {
542  method = FM_METHOD;
543  }
544  break;
545  }
546 
547  }/*of switch heuristic*/
548 
549  /* fprintf(stderr, "in=%d eq=%d method=%d magnitude=", n_cont_in, n_cont_eq, method);print_Value(magnitude);*/
550 
551  switch(method){
552 
554  {
555  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,true,int_p,ofl_ctrl);
556  break;
557  }
559  {
560  ok = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,false,int_p,ofl_ctrl);
561  break;
562  }
563  case (FM_METHOD):
564  {
566  break;
567  }
568  case (JANUS_METHOD):
569  {
571  break;
572  }
573  case (ALL_METHOD):
574  {
575 
576  bool okS = true,okJ = true,okFM = true;
578  ifscdebug(5) {
579  fprintf(stderr,"Janus or Simplex failed. Let's go with FM\n");
580  }
582  ok = okFM;
583  }
584  TRY {
585  if (n_cont_eq >= 10) {
586  okS = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,true,int_p,ofl_ctrl);
587  } else {
588  okS = sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc,false,int_p,ofl_ctrl);
589  }
591 
593 
594  ifscdebug(5) {
595  if (okS != okFM) {
596  fprintf(stderr,"\n[internal_sc_feasibility]: okS %d != okFM %d\n",okS,okFM);
597  sc_default_dump(sc);
598  }
599  if (okJ != okFM) {
600  fprintf(stderr,"\n[internal_sc_feasibility]: okJ %d != okFM %d\n",okJ,okFM);
601  sc_default_dump(sc);
602  }
603  assert(okS == okFM);
604  assert(okJ == okFM);
605  }
606  ok = okFM;
608  }
609  break;
610  }
611  default:
612  {
613  /*rien faire*/
614  break;
615  }
616 
617  }/*of switch method*/
618 
619  return ok;
620 }
621 
622 
623 /* return true is the system is feasible
624  *
625  * In case an exception, due to an overflow or to an error such as
626  * zero divide or a GCD with 0, occurs, return ofl_res. So, an error
627  * may lead to a feasible or a non feasible system.
628  */
629 bool
631  Psysteme sc,
632  bool integer_p,
633  volatile int ofl_ctrl,
634  volatile bool ofl_res)
635 {
636  bool ok = false;
637  volatile bool catch_performed = false;
638  /* Automatic variables read in a CATCH block need to be declared volatile as
639  * specified by the documentation*/
640  int volatile heuristic = 0;
641 
642  ifscdebug(5) {
643  if (sc->dimension < 0) {
644  sc_default_dump(sc);
645  sc_fix(sc);
646  assert(false);
647  }
648  }
649 
650  if (sc_rn_p(sc)) {
651  ifscdebug(5) {
652  fprintf(stderr,"\n sc_rn is given to sc_feasibility_ofl_ctrl : return true");
653  }/* this should be treated somewhere else -> faster */
654  return true;
655  }
656  if (sc_empty_p(sc)) {
657  ifscdebug(5) {
658  fprintf(stderr,"\n sc_empty is given to sc_feasibility_ofl_ctrl : return false");
659  }/*this should be treated somewhere else -> faster*/
660  return false;
661  }
662 
663  if (ofl_ctrl == OFL_CTRL)
664  {
665  ofl_ctrl = FWD_OFL_CTRL;
666  catch_performed = true;
668  ok = ofl_res;
669  catch_performed = false;
670  /*
671  * PLEASE do not remove this warning.
672  *
673  * FC 30/01/95
674  */
676  fprintf(stderr, "\n[sc_feasibility_ofl_ctrl] "
677  "arithmetic error (%d) -> %s\n",
678  heuristic, ofl_res ? "true" : "false");
679  return ok;
680  }
681  }
682 
683  /* What we need to do here:
684  * choose a method or a heuristic predifined by a variable of environment
685  * and catch an overflow exception if it happens DN240203 */
686 
687  heuristic = SWITCH_HEURISTIC_FLAG;/* By default, heuristic flag is 0 */
688  ok = internal_sc_feasibility(sc, heuristic, integer_p, ofl_ctrl);
689  if (catch_performed)
691  return ok;
692 }
693 
694 /* bool sc_fourier_motzkin_faisabilite_ofl(Psysteme s):
695  * test de faisabilite d'un systeme de contraintes lineaires, par projections
696  * successives du systeme selon les differentes variables du systeme
697  *
698  * resultat retourne par la fonction :
699  *
700  * bool : true si le systeme est faisable
701  * false sinon
702  *
703  * Les parametres de la fonction :
704  *
705  * Psysteme s : systeme lineaire
706  *
707  * Le controle de l'overflow est effectue et traite par le retour
708  * du contexte correspondant au dernier CATCH(overflow_error) effectue.
709  *
710  * Back to the version modifying the sc. Calls of this function should store the sc first
711  * or pls call sc_fourier_motzkin_ofl_ctrl_timeout_ctrl DN210203
712  */
713 bool
715 Psysteme s;
716 bool integer_p;
717 int ofl_ctrl;
718 {
719  bool faisable = true;
720 
722  /* maybe timeout_error or overflow_error*/
723  if (ofl_ctrl == FWD_OFL_CTRL) {
724  RETHROW(); /*rethrow whatever the exception is*/
725  } else {
726  fprintf(stderr,"\n[sc_fourier_motzkin_feasibility_ofl_ctrl] without OFL_CTRL => RETURN true\n");
727  return true;/* default is feasible*/
728  }
729  }
730 
731  if (s == NULL) return true;
732 
733  ifscdebug(8)
734  {
735  fprintf(stderr, "[sc_fourier_motzkin_feasibility_ofl_ctrl] system:\n");
737  }
738  if (integer_p) sc_gcd_normalize(s);
740  if (s != NULL && !sc_empty_p(s))
741  {
742  /* a small basis if possible... (FC).
743  */
744  base_rm(sc_base(s));
745  sc_creer_base(s);
746 
747  faisable = sc_fm_project_variables(&s, integer_p, false, ofl_ctrl);
748 
749  sc_rm(s); /*should remove the copy of the sc.*/
750  s = NULL;
751 
752  }
753  else
754  /* sc_kill_db_eg a de'sallouer s a` la detection de
755  sa non-faisabilite */
756  faisable = false;
757 
759 
760  return faisable;
761 }
762 
763 bool
765 Psysteme sc;
766 bool int_p;
767 int ofl_ctrl;
768 {
769  /* Automatic variables read in a CATCH block need to be declared volatile as
770  * specified by the documentation*/
771  Psysteme volatile w = NULL;
772  bool ok = true;
773 
774  if (sc->dimension == 0) return true;
775 
777 
778  ifscdebug(5) {
779  fprintf(stderr,"sc_fourier_motzkin_feasibility_ofl_ctrl_timeout_ctrl fails");
780  }
781 
782 #ifdef FILTERING
783  if (FILTERING_TIMEOUT_FM) alarm(0);
784  if (EXCEPTION_PRINT_FM) {
785  char *directory_name = "feasibility_FM_fail_SC_OUT";
787  }
788 #endif
789 
790  if (w) sc_rm(w);
791 
792  if (ofl_ctrl==FWD_OFL_CTRL) {
793  linear_number_of_exception_thrown -=2;/* there r 2 exceptions here! */
795  } else {
796  fprintf(stderr,"\n[sc_fourier_motzkin_feasibility_ofl_ctrl_timeout_ctrl] without OFL_CTRL => RETURN true\n");
797  return true;
798  }
799  }
800  TRY {
801 
802  w = sc_copy(sc);
803 
804 #ifdef FILTERING
805  if (FILTERING_TIMEOUT_FM) {
806  signal(SIGALRM, filtering_catch_alarm_FM);
807  alarm(FILTERING_TIMEOUT_FM);
808  FM_timeout = false;
809  }
810 #endif
811 
812  if (w) {
813  ok= sc_fourier_motzkin_feasibility_ofl_ctrl(w,int_p,ofl_ctrl);
814  }
815  else ok = true;
816 
817 #ifdef FILTERING
818  if (FILTERING_TIMEOUT_FM) {
819  alarm(0);
820  if (FM_timeout) {
821  char *directory_name = "feasibility_FM_timeout_filtering_SC_OUT";
823  }
824  }
825 #endif
826 
827  }
828 
829  /* if (w) sc_rm(w); sc_fourier_motzkin_feasibility_ctrl_ofl has freed the memory. base */
830 
832 
833  return ok;
834 }
835 
836 bool
837 sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(sc, project_eq_p, int_p, ofl_ctrl)
838 Psysteme sc;
839 bool project_eq_p;
840 bool int_p;
841 int ofl_ctrl;
842 {
843  /* Automatic variables read in a CATCH block need to be declared volatile as
844  * specified by the documentation*/
845  Psysteme volatile w = NULL;
846  bool ok = true;
847 
848  if (sc->dimension == 0) return true;
849 
851 
852  ifscdebug(5) {
853  fprintf(stderr,"\n[sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl] fails");
854  }
855 
856 #ifdef FILTERING
857  if (FILTERING_TIMEOUT_LINEAR_SIMPLEX) alarm(0);
858 
859  if (EXCEPTION_PRINT_LINEAR_SIMPLEX) {
860  char *directory_name = "feasibility_linear_simplex_fail_SC_OUT";
862  }
863 #endif
864 
865  if (w) sc_rm(w);
866  if (ofl_ctrl == FWD_OFL_CTRL) {
867  linear_number_of_exception_thrown -=2;/*there r 2 exceptions here!*/
869  } else {
870  fprintf(stderr,"\n[sc_simplex_feasibility_ofl_ctrl_timeout_ctrl] without OFL_CTRL => RETURN true\n");
871  return true;/* default is feasible*/
872  }
873  }
874  TRY {
875 
876 #ifdef FILTERING
877  if (FILTERING_TIMEOUT_LINEAR_SIMPLEX) {
878  signal(SIGALRM, filtering_catch_alarm_S);
879  alarm(FILTERING_TIMEOUT_LINEAR_SIMPLEX);
880  S_timeout = false;
881  }
882 #endif
883 
884  if (project_eq_p) {
885  w = sc_copy(sc);
886  ok = sc_fm_project_variables(&w, int_p, true, ofl_ctrl);
887  ok = sc_simplex_feasibility_ofl_ctrl(w,ofl_ctrl);
888  }else {
889  ok = sc_simplex_feasibility_ofl_ctrl(sc,ofl_ctrl);
890  }
891 
892 #ifdef FILTERING
893  if (FILTERING_TIMEOUT_LINEAR_SIMPLEX) {
894  alarm(0);
895  if (S_timeout) {
896  char *directory_name = "feasibility_linear_simplex_timeout_filtering_SC_OUT";
898  }
899  }
900 #endif
901 
902  }
903 
904  if (w) sc_rm(w);
906 
907  return ok;
908 }
909 
910 bool
912 Psysteme sc;
913 bool ofl_ctrl;
914 {
915  /* Automatic variables read in a CATCH block need to be declared volatile as
916  * specified by the documentation*/
917  Psysteme volatile w = NULL;
918  int ok=0;
919 
920  /*DN: We should be sure that the sc is not null in the sc_feasibility_ofl_ctrl, but for direct calls of Janus ...*/
921  if (sc) {
922  if (sc->dimension == 0) return true;
923  }
924  else return true;
925 
926  /* sc_empty_p is filtered, (sc_fix is called), so there's no other reason for janus to fail ...
927  * maybe a sc_not_easy_to_see_empty */
928  /* TODO aware of vectors of one element: 0 <= 1.
929  * treating it here is better than in Janus */
930 
932 
933  ifscdebug(5) {
934  fprintf(stderr,"\n[sc_janus_feasibility_ofl_ctrl_timeout_ctrl] fails");
935  }
936 
937 #ifdef FILTERING
938  if (FILTERING_TIMEOUT_JANUS) alarm(0);
939 
940  if (EXCEPTION_PRINT_JANUS) {
941  char *directory_name = "feasibility_janus_fail_SC_OUT";
943  }
944 #endif
945 
946  if (w) sc_rm(w);
947  linear_number_of_exception_thrown -=1;/*there r 2 exceptions here!*/
949  }
950  TRY {
951  if (sc) {w = sc_copy(sc);}
952  else return true;
953  if (w) {sc_fix(w);}
954 
955  if (w) {
956 
957 #ifdef FILTERING
958  if (FILTERING_TIMEOUT_JANUS) {
959  signal(SIGALRM, filtering_catch_alarm_J);
960  alarm(FILTERING_TIMEOUT_JANUS);
961  J_timeout = false;
962  }
963 #endif
964 
965  ok = sc_janus_feasibility(w); /*sc_janus_feasibility returns type int, not boolean*/
966 
967 #ifdef FILTERING
968  if (FILTERING_TIMEOUT_JANUS) {
969  alarm(0);
970  if (J_timeout){
971  char *directory_name = "feasibility_janus_timeout_filtering_SC_OUT";
973  }
974  }
975 #endif
976 
977  } else return true;
978 
979  }
980 
982 
983  if (ok<3) {
984  /* result found*/
985  if (w) sc_rm(w);
986  if (ok > 0) return true;
987  else return false;
988  } else {
989  /* result not found*/
990  ifscdebug(5) {
991  if (ok ==7) fprintf(stderr,"TRIED JANUS BUT OVERFLOW !!\n");
992  if (ok ==6) fprintf(stderr,"TRIED JANUS BUT BUG OF PROGRAMMATION IN JANUS !!\n");
993  if (ok ==5) fprintf(stderr,"TRIED JANUS BUT WRONG PARAMETER !!\n");
994  if (ok ==4) fprintf(stderr,"TRIED JANUS BUT ARRAY OUT OF BOUNDARY !!\n");
995  if (ok ==3) fprintf(stderr,"TRIED JANUS BUT NUMBER OF PIVOTAGE TOO BIG, MIGHT BOUCLE !!\n");
996  if (ok ==8) fprintf(stderr,"TRIED JANUS BUT pivot anormally small !!\n");
997  if (ok ==9) fprintf(stderr,"Janus is not ready for this system of constraints !!\n");
998  }
999  if (w) sc_rm(w);
1000  if (ofl_ctrl == FWD_OFL_CTRL) {
1002  } else {
1003  fprintf(stderr,"\n[sc_janus_feasibility_ofl_ctrl_timeout_ctrl] without OFL_CTRL => RETURN true\n");
1004  return true;/* default is feasible*/
1005  }
1006  }
1007  return(ok);
1008 }
1009 
1010 // moved here from pips
1011 
1013 {
1014  int MAXCOEFFICIENT = 1000;
1015  Value val_max = int_to_value(MAXCOEFFICIENT);
1016  Pcontrainte ineg, ineg1;
1017  for (ineg = sc->inegalites; ineg != NULL; ineg = ineg1)
1018  {
1019  Pvecteur vec = ineg->vecteur,v;
1020  for (v = vec; v !=NULL && ineg->vecteur != VECTEUR_NUL; v = v->succ)
1021  {
1022  Value val = v->val;
1023  Variable var =v->var;
1024  if (value_gt(value_abs(val),val_max) && (var!=TCST))
1025  eq_set_vect_nul(ineg);
1026  }
1027  ineg1 = ineg->succ;
1028  }
1030  return sc;
1031 }
1032 
1034 {
1035  bool retour = true;
1036  // try fast check
1037  int fast_check = sc_check_inequality_redundancy(contrainte_make(v), prec);
1038 
1039  // ok, feasible because ineq is redundant wrt prec
1040  // or ok, system {prec + ineq} is infeasible
1041  if (fast_check == 1 || fast_check == 2)
1042  return fast_check == 1;
1043  // ELSE no result, try slow version. default is feasible.
1044  assert(fast_check == 0);
1045 
1046  // NN: 25/09/2001, try to avoid overflows by using a smaller system:
1047  // only constraints transitively connected to a constraint referencing
1048  // a variable of interest in v are taken from prec.
1049  // sc_restricted_to_variables_transitive_closure(sc,vars)
1050 
1051  Psysteme s_dup = sc_dup(prec);
1052  Pbase vars = make_base_from_vect(v);
1054 
1055  // nofoverflows is used to save the number of overflows before the call
1056  // to sc_integer_feasibility_ofl_ctrl
1057 
1058  int nofoverflows = linear_number_of_exception_thrown;
1059 
1060  Psysteme s = sc_dup(s_res);
1061  // add the inegality to the system
1062  sc_constraint_add(s, contrainte_make(v), false);
1063  retour = sc_integer_feasibility_ofl_ctrl(s, OFL_CTRL,true);
1064  sc_rm(s);
1065 
1066  // if retour = true : the system is feasible or there are overflows
1067  // (our goal is to verify if retour is false or not)
1068  // if there are overflows (the value of nofoverflows will be changed),
1069  // we simplify the system and recalcul the feasibility
1070 
1071  if (retour && nofoverflows < linear_number_of_exception_thrown)
1072  {
1073  // there has been an overflow, let us try something else...
1074  Psysteme new_s = sc_dup(prec);
1075  new_s = simplify_big_coeff(new_s);
1076  sc_constraint_add(new_s, contrainte_make(v), false);
1077  retour = sc_integer_feasibility_ofl_ctrl(new_s, OFL_CTRL,true);
1078  sc_rm(new_s);
1079  }
1080  return retour;
1081 }
#define CATCH(what)
@ overflow_error
@ any_exception_error
catch all
#define THROW(what)
#define UNCATCH(what)
#define RETHROW()
#define TRY
#define VALUE_ZERO
#define int_to_value(i)
end LINEAR_VALUE_IS_INT
#define value_gt(v1, v2)
#define value_notzero_p(val)
#define value_one_p(val)
#define value_assign(ref, val)
assigments
#define value_zero_p(val)
int Value
#define value_abs(val)
#define value_lt(v1, v2)
#define value_posz_p(val)
int linear_number_of_exception_thrown
bool linear_use_gmp(void)
whether linear is to use gmp
Definition: errors.c:454
Pbase make_base_from_vect(Pvecteur pv)
Definition: base.c:109
#define contrainte_vecteur(c)
passage au champ vecteur d'une contrainte "a la Newgen"
Pcontrainte contrainte_make(Pvecteur pv)
Pcontrainte contrainte_make(Pvecteur pv): allocation et initialisation d'une contrainte avec un vecte...
Definition: alloc.c:73
void eq_set_vect_nul(Pcontrainte)
void_eq_set_vect_nul(Pcontrainte c): transformation d'une contrainte en une contrainte triviale 0 == ...
Definition: unaires.c:84
void * malloc(YYSIZE_T)
void free(void *)
bool sc_janus_feasibility(Psysteme sc)
Compute feasibility, using custom Janus function if set, fallback function otherwise.
void vect_fprint(FILE *f, Pvecteur v, get_variable_name_t variable_name)
void vect_fprint(FILE * f, Pvecteur v, char * (*variable_name)()): impression d'un vecteur creux v su...
Definition: io.c:124
int vect_size(Pvecteur v)
package vecteur - reductions
Definition: reductions.c:47
#define assert(ex)
Definition: newgen_assert.h:41
bool sc_rn_p(Psysteme sc)
bool sc_rn_p(Psysteme sc): check if the set associated to sc is the whole space, rn
Definition: sc_alloc.c:369
void sc_creer_base(Psysteme ps)
void sc_creer_base(Psysteme ps): initialisation des parametres dimension et base d'un systeme lineair...
Definition: sc_alloc.c:129
void sc_fix(Psysteme s)
fix system s for coherency of the base and number of things.
Definition: sc_alloc.c:141
void sc_rm(Psysteme ps)
void sc_rm(Psysteme ps): liberation de l'espace memoire occupe par le systeme de contraintes ps;
Definition: sc_alloc.c:277
bool sc_empty_p(Psysteme sc)
bool sc_empty_p(Psysteme sc): check if the set associated to sc is the constant sc_empty or not.
Definition: sc_alloc.c:350
Psysteme sc_dup(Psysteme ps)
Psysteme sc_dup(Psysteme ps): should becomes a link.
Definition: sc_alloc.c:176
Psysteme sc_copy(Psysteme ps)
Psysteme sc_copy(Psysteme ps): duplication d'un systeme (allocation et copie complete des champs sans...
Definition: sc_alloc.c:230
void sc_rm_empty_constraints(Psysteme ps, bool process_equalities)
package sc: elimination de redondance simple
Definition: sc_elim_eq.c:56
Psysteme sc_safe_elim_db_constraints(Psysteme ps)
The returned value must be used because they argument is freed when the system is not feasible.
int sc_check_inequality_redundancy(Pcontrainte ineq, Psysteme ps)
int sc_check_inequality_redundancy(Pcontrainte ineq, Psysteme ps) Check if an inequality ineq,...
bool sc_fourier_motzkin_feasibility_ofl_ctrl(Psysteme s, bool integer_p, int ofl_ctrl)
bool sc_fourier_motzkin_faisabilite_ofl(Psysteme s): test de faisabilite d'un systeme de contraintes ...
bool efficient_sc_check_inequality_feasibility(Pvecteur v, Psysteme prec)
#define JANUS_METHOD
void decision_data(Pcontrainte c, int volatile *pc, int volatile *pv, Value *magnitude, int weight)
just a test to improve the Simplex/FM decision.
bool sc_rational_feasibility_ofl_ctrl(Psysteme sc, int ofl_ctrl, bool ofl_res)
static int feasibility_sc_counter
static bool sc_fm_project_variables(Psysteme volatile *ps1, bool integer_p, bool use_eq_only, int ofl_ctrl)
project in s1 (which is modified) using equalities or both equalities and inequalities.
bool sc_integer_feasibility_ofl_ctrl(Psysteme sc, int ofl_ctrl, bool ofl_res)
static Psysteme simplify_big_coeff(Psysteme sc)
#define FM_METHOD
#define HEURISTIC4
#define HEURISTIC2
#define LINEAR_SIMPLEX_NO_PROJECT_EQ_METHOD
bool sc_fourier_motzkin_feasibility_ofl_ctrl_timeout_ctrl(Psysteme sc, bool int_p, int ofl_ctrl)
static bool internal_sc_feasibility(Psysteme sc, int heuristic, bool int_p, int ofl_ctrl)
means LINEAR_SIMPLEX :-)
static int method_used
bool sc_simplexe_feasibility_ofl_ctrl_timeout_ctrl(Psysteme sc, bool project_eq_p, bool int_p, int ofl_ctrl)
bool sc_feasibility_ofl_ctrl(Psysteme sc, bool integer_p, volatile int ofl_ctrl, volatile bool ofl_res)
return true is the system is feasible
char * default_variable_to_string(Variable)
Definition: sc_debug.c:245
bool S_timeout
#define SWITCH_HEURISTIC_FLAG
#define ALL_METHOD
#define LINEAR_SIMPLEX_PROJECT_EQ_METHOD
#define HEURISTIC3
bool FM_timeout
bool J_timeout
bool sc_janus_feasibility_ofl_ctrl_timeout_ctrl(Psysteme sc, bool ofl_ctrl)
static Variable chose_variable_to_project_for_feasability(Psysteme s, Pbase b, bool ineq)
chose the next variable in base b for projection in system s.
#define HEURISTIC1
We can add other heuristic if we need in an easy way.
Psysteme sc_constraint_add(Psysteme sc, Pcontrainte c, bool equality)
Definition: sc_insert_eq.c:115
void sc_fprint(FILE *fp, Psysteme ps, get_variable_name_t nom_var)
void sc_fprint(FILE * f, Psysteme ps, char * (*nom_var)()): cette fonction imprime dans le fichier po...
Definition: sc_io.c:220
void sc_default_dump_to_files(Psysteme sc, int sc_nb, char *directory_name)
void sc_default_dump_to_files(Psysteme sc, sc_nb,directory_name):
Definition: sc_io.c:288
void sc_default_dump(Psysteme sc)
void sc_default_dump(Psysteme sc): dump to stderr
Definition: sc_io.c:170
int fprintf()
test sc_min : ce test s'appelle par : programme fichier1.data fichier2.data ...
Psysteme sc_restricted_to_variables_transitive_closure(Psysteme sc, Pbase variables)
for an improved dependence test (Beatrice Creusillet)
Definition: sc_misc.c:64
void sc_gcd_normalize(Psysteme ps)
sc_gcd_normalize(ps)
Psysteme sc_normalize(Psysteme ps)
Psysteme sc_normalize(Psysteme ps): normalisation d'un systeme d'equation et d'inequations lineaires ...
bool sc_simplex_feasibility_ofl_ctrl(Psysteme sys, int ofl_ctrl)
Main Function.
static bool ok
Pvecteur vecteur
struct Scontrainte * succ
Pcontrainte inegalites
Definition: sc-local.h:71
int dimension
Definition: sc-local.h:74
le type des coefficients dans les vecteurs: Value est defini dans le package arithmetique
Definition: vecteur-local.h:89
Value val
Definition: vecteur-local.h:91
struct Svecteur * succ
Definition: vecteur-local.h:92
#define TCST
VARIABLE REPRESENTANT LE TERME CONSTANT.
#define val_of(varval)
#define VECTEUR_NUL
DEFINITION DU VECTEUR NUL.
#define base_rm(b)
void * Variable
arithmetique is a requirement for vecteur, but I do not want to inforce it in all pips files....
Definition: vecteur-local.h:60
#define FWD_OFL_CTRL
#define var_of(varval)
#define OFL_CTRL
I do thing that overflows are managed in a very poor manner.
Pbase base_copy(Pbase b)
Direct duplication.
Definition: alloc.c:300
void vect_erase_var(Pvecteur *ppv, Variable v)
void vect_erase_var(Pvecteur * ppv, Variable v): projection du vecteur *ppv selon la direction v (i....
Definition: unaires.c:106