PPL  1.2
PIP_Problem.cc
Go to the documentation of this file.
1 /* PIP_Problem class implementation: non-inline functions.
2  Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it>
3  Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com)
4 
5 This file is part of the Parma Polyhedra Library (PPL).
6 
7 The PPL is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 The PPL is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA.
20 
21 For the most up-to-date information see the Parma Polyhedra Library
22 site: http://bugseng.com/products/ppl/ . */
23 
24 #include "ppl-config.h"
25 #include "PIP_Problem_defs.hh"
26 #include "PIP_Tree_defs.hh"
27 
28 namespace PPL = Parma_Polyhedra_Library;
29 
31 std::ostream&
32 PPL::IO_Operators::operator<<(std::ostream& s, const PIP_Problem& pip) {
33  s << "Space dimension: " << pip.space_dimension();
34  s << "\nConstraints:";
36  i_end = pip.constraints_end(); i != i_end; ++i) {
37  s << "\n" << *i;
38  }
39  s << "\nProblem parameters: " << pip.parameter_space_dimensions();
41  s << "\nNo big-parameter set.\n";
42  }
43  else {
44  s << "\nBig-parameter: " << Variable(pip.get_big_parameter_dimension());
45  }
46  s << "\n";
47  return s;
48 }
49 
51  : external_space_dim(dim),
52  internal_space_dim(0),
53  status(PARTIALLY_SATISFIABLE),
54  current_solution(0),
55  input_cs(),
56  first_pending_constraint(0),
57  parameters(),
58  initial_context(),
59  big_parameter_dimension(not_a_dimension()) {
60  // Check for space dimension overflow.
61  if (dim > max_space_dimension()) {
62  throw std::length_error("PPL::PIP_Problem::PIP_Problem(dim):\n"
63  "dim exceeds the maximum allowed "
64  "space dimension.");
65  }
67  PPL_ASSERT(OK());
68 }
69 
71  : external_space_dim(y.external_space_dim),
72  internal_space_dim(y.internal_space_dim),
73  status(y.status),
74  current_solution(0),
75  input_cs(y.input_cs),
76  first_pending_constraint(y.first_pending_constraint),
77  parameters(y.parameters),
78  initial_context(y.initial_context),
79  big_parameter_dimension(y.big_parameter_dimension) {
80  if (y.current_solution != 0) {
83  }
85  PPL_ASSERT(OK());
86 }
87 
89  delete current_solution;
90 }
91 
92 void
94  control_parameters[CUTTING_STRATEGY] = CUTTING_STRATEGY_FIRST;
95  control_parameters[PIVOT_ROW_STRATEGY] = PIVOT_ROW_STRATEGY_FIRST;
96 }
97 
98 void
100  for (dimension_type i = CONTROL_PARAMETER_NAME_SIZE; i-- > 0; ) {
101  control_parameters[i] = y.control_parameters[i];
102  }
103 }
104 
107  switch (status) {
108 
109  case UNSATISFIABLE:
110  PPL_ASSERT(OK());
111  return UNFEASIBLE_PIP_PROBLEM;
112 
113  case OPTIMIZED:
114  PPL_ASSERT(OK());
115  return OPTIMIZED_PIP_PROBLEM;
116 
117  case PARTIALLY_SATISFIABLE:
118  {
119  PIP_Problem& x = const_cast<PIP_Problem&>(*this);
120  // Allocate PIP solution tree root, if needed.
121  if (current_solution == 0) {
122  x.current_solution = new PIP_Solution_Node(this);
123  }
124 
125  // Properly resize context matrix.
126  const dimension_type new_num_cols = parameters.size() + 1;
127  const dimension_type old_num_cols = initial_context.num_columns();
128  if (old_num_cols < new_num_cols) {
129  x.initial_context.add_zero_columns(new_num_cols - old_num_cols);
130  }
131 
132  // Computed once for all (to be used inside loop).
133  const Variables_Set::const_iterator param_begin = parameters.begin();
134  const Variables_Set::const_iterator param_end = parameters.end();
135 
136  // This flag will be set if we insert a pending constraint
137  // in the initial context.
138  bool check_feasible_context = false;
139 
140  // Go through all pending constraints.
141  for (Constraint_Sequence::const_iterator
142  cs_i = nth_iter(input_cs, first_pending_constraint),
143  cs_end = input_cs.end(); cs_i != cs_end; ++cs_i) {
144  const Constraint& c = *cs_i;
145  const dimension_type c_space_dim = c.space_dimension();
146  PPL_ASSERT(external_space_dim >= c_space_dim);
147 
148  // Constraints having a non-zero variable coefficient
149  // should not be inserted in context.
150  if (!c.expression().all_zeroes_except(parameters, 1, c_space_dim + 1)) {
151  continue;
152  }
153 
154  check_feasible_context = true;
155 
156  x.initial_context.add_zero_rows(1);
157 
158  Row& row = x.initial_context[x.initial_context.num_rows()-1];
159 
160  {
161  Row::iterator itr = row.end();
162 
163  if (c.inhomogeneous_term() != 0) {
164  itr = row.insert(0, c.inhomogeneous_term());
165  // Adjust inhomogeneous term if strict.
166  if (c.is_strict_inequality()) {
167  --(*itr);
168  }
169  }
170  else {
171  // Adjust inhomogeneous term if strict.
172  if (c.is_strict_inequality()) {
173  itr = row.insert(0, -1);
174  }
175  }
176  dimension_type i = 1;
177 
178  // TODO: This loop may be optimized more, if needed.
179  // If the size of param_end is expected to be greater than the
180  // number of nonzeroes of c in most cases, then this implementation
181  // can't be optimized further.
182  // itr may still be end(), but it can still be used as hint.
183  for (Variables_Set::const_iterator
184  pi = param_begin; pi != param_end; ++pi, ++i) {
185  if (*pi < c_space_dim) {
186  Coefficient_traits::const_reference coeff_pi
187  = c.coefficient(Variable(*pi));
188  if (coeff_pi != 0) {
189  itr = row.insert(itr, i, coeff_pi);
190  }
191  }
192  else {
193  break;
194  }
195  }
196  }
197 
198  // If it is an equality, also insert its negation.
199  if (c.is_equality()) {
200  x.initial_context.add_zero_rows(1);
201 
202  // The reference `row' has been invalidated.
203 
204  Row& last_row = x.initial_context[x.initial_context.num_rows()-1];
205 
206  last_row = x.initial_context[x.initial_context.num_rows()-2];
207 
208  for (Row::iterator i = last_row.begin(),
209  i_end = last_row.end(); i != i_end; ++i) {
210  neg_assign(*i);
211  }
212  }
213  }
214 
215  if (check_feasible_context) {
216  // Check for feasibility of initial context.
217  Matrix<Row> ctx_copy(initial_context);
219  // Problem found to be unfeasible.
220  delete x.current_solution;
221  x.current_solution = 0;
222  x.status = UNSATISFIABLE;
223  PPL_ASSERT(OK());
224  return UNFEASIBLE_PIP_PROBLEM;
225  }
226  }
227 
228  // Update tableau and mark constraints as no longer pending.
230  external_space_dim,
231  first_pending_constraint,
232  input_cs,
233  parameters);
234  x.internal_space_dim = external_space_dim;
235  x.first_pending_constraint = input_cs.size();
236 
237  // Actually solve problem.
239  check_feasible_context,
240  initial_context,
241  parameters,
242  external_space_dim,
243  /*indent_level=*/ 0);
244  // Update problem status.
245  x.status = (x.current_solution != 0) ? OPTIMIZED : UNSATISFIABLE;
246 
247  PPL_ASSERT(OK());
248  return (x.current_solution != 0)
251  } // End of handler for PARTIALLY_SATISFIABLE case.
252 
253  } // End of switch.
254 
255  // We should not be here!
256  PPL_UNREACHABLE;
257  return UNFEASIBLE_PIP_PROBLEM;
258 }
259 
262  if (status == PARTIALLY_SATISFIABLE) {
263  solve();
264  }
265  return current_solution;
266 }
267 
270  if (status == PARTIALLY_SATISFIABLE) {
271  solve();
272  }
273  return current_solution;
274 }
275 
276 bool
278 #ifndef NDEBUG
279  using std::endl;
280  using std::cerr;
281 #endif
282 
283  if (external_space_dim < internal_space_dim) {
284 #ifndef NDEBUG
285  cerr << "The internal space dimension of the PIP_Problem is "
286  << "greater than its external space dimension."
287  << endl;
288  ascii_dump(cerr);
289 #endif
290  return false;
291  }
292 
293  // Constraint system should be space dimension compatible.
294  const dimension_type input_cs_num_rows = input_cs.size();
295  for (dimension_type i = input_cs_num_rows; i-- > 0; ) {
296  if (input_cs[i].space_dimension() > external_space_dim) {
297 #ifndef NDEBUG
298  cerr << "The space dimension of the PIP_Problem is smaller than "
299  << "the space dimension of one of its constraints."
300  << endl;
301  ascii_dump(cerr);
302 #endif
303  return false;
304  }
305  }
306 
307  // Test validity of control parameter values.
308  Control_Parameter_Value strategy = control_parameters[CUTTING_STRATEGY];
309  if (strategy != CUTTING_STRATEGY_FIRST
310  && strategy != CUTTING_STRATEGY_DEEPEST
311  && strategy != CUTTING_STRATEGY_ALL) {
312 #ifndef NDEBUG
313  cerr << "Invalid value for the CUTTING_STRATEGY control parameter."
314  << endl;
315  ascii_dump(cerr);
316 #endif
317  return false;
318  }
319 
320  strategy = control_parameters[PIVOT_ROW_STRATEGY];
321  if (strategy < PIVOT_ROW_STRATEGY_FIRST
322  || strategy > PIVOT_ROW_STRATEGY_MAX_COLUMN) {
323 #ifndef NDEBUG
324  cerr << "Invalid value for the PIVOT_ROW_STRATEGY control parameter."
325  << endl;
326  ascii_dump(cerr);
327 #endif
328  return false;
329  }
330 
331  if (big_parameter_dimension != not_a_dimension()
332  && parameters.count(big_parameter_dimension) == 0) {
333 #ifndef NDEBUG
334  cerr << "The big parameter is set, but it is not a parameter." << endl;
335  ascii_dump(cerr);
336 #endif
337  return false;
338  }
339 
340  if (!parameters.OK()) {
341  return false;
342  }
343  if (!initial_context.OK()) {
344  return false;
345  }
346 
347  if (current_solution != 0) {
348  // Check well formedness of the solution tree.
349  if (!current_solution->OK()) {
350 #ifndef NDEBUG
351  cerr << "The computed solution tree is broken.\n";
352  ascii_dump(cerr);
353 #endif
354  return false;
355  }
356  // Check that all nodes in the solution tree belong to *this.
357  if (!current_solution->check_ownership(this)) {
358 #ifndef NDEBUG
359  cerr << "There are nodes in the solution tree "
360  << "that are not owned by *this.\n";
361  ascii_dump(cerr);
362 #endif
363  return false;
364  }
365  }
366 
367  // All checks passed.
368  return true;
369 }
370 
371 void
372 PPL::PIP_Problem::ascii_dump(std::ostream& s) const {
373  using namespace IO_Operators;
374  s << "\nexternal_space_dim: " << external_space_dim << "\n";
375  s << "\ninternal_space_dim: " << internal_space_dim << "\n";
376 
377  const dimension_type input_cs_size = input_cs.size();
378 
379  s << "\ninput_cs( " << input_cs_size << " )\n";
380  for (dimension_type i = 0; i < input_cs_size; ++i) {
381  input_cs[i].ascii_dump(s);
382  }
383 
384  s << "\nfirst_pending_constraint: " << first_pending_constraint << "\n";
385 
386  s << "\nstatus: ";
387  switch (status) {
388  case UNSATISFIABLE:
389  s << "UNSATISFIABLE";
390  break;
391  case OPTIMIZED:
392  s << "OPTIMIZED";
393  break;
394  case PARTIALLY_SATISFIABLE:
395  s << "PARTIALLY_SATISFIABLE";
396  break;
397  }
398  s << "\n";
399 
400  s << "\nparameters";
401  parameters.ascii_dump(s);
402 
403  s << "\ninitial_context\n";
404  initial_context.ascii_dump(s);
405 
406  s << "\ncontrol_parameters\n";
407  for (dimension_type i = 0; i < CONTROL_PARAMETER_NAME_SIZE; ++i) {
408  const Control_Parameter_Value value = control_parameters[i];
409  switch (value) {
410  case CUTTING_STRATEGY_FIRST:
411  s << "CUTTING_STRATEGY_FIRST";
412  break;
413  case CUTTING_STRATEGY_DEEPEST:
414  s << "CUTTING_STRATEGY_DEEPEST";
415  break;
416  case CUTTING_STRATEGY_ALL:
417  s << "CUTTING_STRATEGY_ALL";
418  break;
419  case PIVOT_ROW_STRATEGY_FIRST:
420  s << "PIVOT_ROW_STRATEGY_FIRST";
421  break;
422  case PIVOT_ROW_STRATEGY_MAX_COLUMN:
423  s << "PIVOT_ROW_STRATEGY_MAX_COLUMN";
424  break;
425  default:
426  s << "Invalid control parameter value";
427  }
428  s << "\n";
429  }
430 
431  s << "\nbig_parameter_dimension: " << big_parameter_dimension << "\n";
432 
433  s << "\ncurrent_solution: ";
434  if (current_solution == 0) {
435  s << "BOTTOM\n";
436  }
437  else if (const PIP_Decision_Node* const dec
438  = current_solution->as_decision()) {
439  s << "DECISION\n";
440  dec->ascii_dump(s);
441  }
442  else {
443  const PIP_Solution_Node* const sol = current_solution->as_solution();
444  PPL_ASSERT(sol != 0);
445  s << "SOLUTION\n";
446  sol->ascii_dump(s);
447  }
448 }
449 
451 
452 bool
453 PPL::PIP_Problem::ascii_load(std::istream& s) {
454  std::string str;
455  if (!(s >> str) || str != "external_space_dim:") {
456  return false;
457  }
458 
459  if (!(s >> external_space_dim)) {
460  return false;
461  }
462 
463  if (!(s >> str) || str != "internal_space_dim:") {
464  return false;
465  }
466 
467  if (!(s >> internal_space_dim)) {
468  return false;
469  }
470 
471  if (!(s >> str) || str != "input_cs(") {
472  return false;
473  }
474 
475  dimension_type input_cs_size;
476 
477  if (!(s >> input_cs_size)) {
478  return false;
479  }
480 
481  if (!(s >> str) || str != ")") {
482  return false;
483  }
484 
486  for (dimension_type i = 0; i < input_cs_size; ++i) {
487  if (!c.ascii_load(s)) {
488  return false;
489  }
490  input_cs.push_back(c);
491  }
492 
493  if (!(s >> str) || str != "first_pending_constraint:") {
494  return false;
495  }
496 
497  if (!(s >> first_pending_constraint)) {
498  return false;
499  }
500 
501  if (!(s >> str) || str != "status:") {
502  return false;
503  }
504 
505  if (!(s >> str)) {
506  return false;
507  }
508 
509  if (str == "UNSATISFIABLE") {
510  status = UNSATISFIABLE;
511  }
512  else if (str == "OPTIMIZED") {
513  status = OPTIMIZED;
514  }
515  else if (str == "PARTIALLY_SATISFIABLE") {
516  status = PARTIALLY_SATISFIABLE;
517  }
518  else {
519  return false;
520  }
521 
522  if (!(s >> str) || str != "parameters") {
523  return false;
524  }
525 
526  if (!parameters.ascii_load(s)) {
527  return false;
528  }
529 
530  if (!(s >> str) || str != "initial_context") {
531  return false;
532  }
533 
534  if (!initial_context.ascii_load(s)) {
535  return false;
536  }
537 
538  if (!(s >> str) || str != "control_parameters") {
539  return false;
540  }
541 
542  for (dimension_type i = 0; i < CONTROL_PARAMETER_NAME_SIZE; ++i) {
543  if (!(s >> str)) {
544  return false;
545  }
547  if (str == "CUTTING_STRATEGY_FIRST") {
548  value = CUTTING_STRATEGY_FIRST;
549  }
550  else if (str == "CUTTING_STRATEGY_DEEPEST") {
551  value = CUTTING_STRATEGY_DEEPEST;
552  }
553  else if (str == "CUTTING_STRATEGY_ALL") {
554  value = CUTTING_STRATEGY_ALL;
555  }
556  else if (str == "PIVOT_ROW_STRATEGY_FIRST") {
557  value = PIVOT_ROW_STRATEGY_FIRST;
558  }
559  else if (str == "PIVOT_ROW_STRATEGY_MAX_COLUMN") {
560  value = PIVOT_ROW_STRATEGY_MAX_COLUMN;
561  }
562  else {
563  return false;
564  }
565  control_parameters[i] = value;
566  }
567 
568  if (!(s >> str) || str != "big_parameter_dimension:") {
569  return false;
570  }
571  if (!(s >> big_parameter_dimension)) {
572  return false;
573  }
574 
575  // Release current_solution tree (if any).
576  delete current_solution;
577  current_solution = 0;
578  // Load current_solution (if any).
579  if (!(s >> str) || str != "current_solution:") {
580  return false;
581  }
582  if (!(s >> str)) {
583  return false;
584  }
585  if (str == "BOTTOM") {
586  current_solution = 0;
587  }
588  else if (str == "DECISION") {
589  PIP_Decision_Node* const dec = new PIP_Decision_Node(0, 0, 0);
590  current_solution = dec;
591  if (!dec->ascii_load(s)) {
592  return false;
593  }
594  dec->set_owner(this);
595  }
596  else if (str == "SOLUTION") {
597  PIP_Solution_Node* const sol = new PIP_Solution_Node(0);
598  current_solution = sol;
599  if (!sol->ascii_load(s)) {
600  return false;
601  }
602  sol->set_owner(this);
603  }
604  else {
605  // Unknown node kind.
606  return false;
607  }
608 
609  PPL_ASSERT(OK());
610  return true;
611 }
612 
613 void
615  external_space_dim = 0;
616  internal_space_dim = 0;
617  status = PARTIALLY_SATISFIABLE;
618  if (current_solution != 0) {
619  delete current_solution;
620  current_solution = 0;
621  }
622  input_cs.clear();
623  first_pending_constraint = 0;
624  parameters.clear();
625  initial_context.clear();
626  control_parameters_init();
627  big_parameter_dimension = not_a_dimension();
628 }
629 
630 void
633  const dimension_type m_params) {
634  // Adding no space dims at all is a no-op:
635  // this avoids invalidating problem status (if it was optimized).
636  if (m_vars == 0 && m_params == 0) {
637  return;
638  }
639 
640  // The space dimension of the resulting PIP problem should not
641  // overflow the maximum allowed space dimension.
642  dimension_type available = max_space_dimension() - space_dimension();
643  bool should_throw = (m_vars > available);
644  if (!should_throw) {
645  available -= m_vars;
646  should_throw = (m_params > available);
647  }
648  if (should_throw) {
649  throw std::length_error("PPL::PIP_Problem::"
650  "add_space_dimensions_and_embed(m_v, m_p):\n"
651  "adding m_v+m_p new space dimensions exceeds "
652  "the maximum allowed space dimension.");
653  }
654  // First add PIP variables ...
655  external_space_dim += m_vars;
656  // ... then add PIP parameters.
657  for (dimension_type i = m_params; i-- > 0; ) {
658  parameters.insert(Variable(external_space_dim));
659  ++external_space_dim;
660  }
661  // Update problem status.
662  if (status != UNSATISFIABLE) {
663  status = PARTIALLY_SATISFIABLE;
664  }
665  PPL_ASSERT(OK());
666 }
667 
668 void
671  if (p_vars.space_dimension() > external_space_dim) {
672  throw std::invalid_argument("PPL::PIP_Problem::"
673  "add_to_parameter_space_dimension(p_vars):\n"
674  "*this and p_vars are dimension "
675  "incompatible.");
676  }
677  const dimension_type original_size = parameters.size();
678  parameters.insert(p_vars.begin(), p_vars.end());
679  // Do not allow to turn variables into parameters.
680  for (Variables_Set::const_iterator p = p_vars.begin(),
681  end = p_vars.end(); p != end; ++p) {
682  if (*p < internal_space_dim) {
683  throw std::invalid_argument("PPL::PIP_Problem::"
684  "add_to_parameter_space_dimension(p_vars):"
685  "p_vars contain variable indices.");
686  }
687  }
688 
689  // If a new parameter was inserted, set the internal status to
690  // PARTIALLY_SATISFIABLE.
691  if (parameters.size() != original_size && status != UNSATISFIABLE) {
692  status = PARTIALLY_SATISFIABLE;
693  }
694 }
695 
696 void
698  if (c.space_dimension() > external_space_dim) {
699  std::ostringstream s;
700  s << "PPL::PIP_Problem::add_constraint(c):\n"
701  << "dim == "<< external_space_dim << " and c.space_dimension() == "
702  << c.space_dimension() << " are dimension incompatible.";
703  throw std::invalid_argument(s.str());
704  }
705  input_cs.push_back(c);
706  // Update problem status.
707  if (status != UNSATISFIABLE) {
708  status = PARTIALLY_SATISFIABLE;
709  }
710 }
711 
712 void
715  ci_end = cs.end(); ci != ci_end; ++ci) {
716  add_constraint(*ci);
717  }
718 }
719 
720 bool
722  if (status == PARTIALLY_SATISFIABLE) {
723  solve();
724  }
725  return status == OPTIMIZED;
726 }
727 
728 void
730  switch (value) {
731  case CUTTING_STRATEGY_FIRST:
732  // Intentionally fall through.
733  case CUTTING_STRATEGY_DEEPEST:
734  // Intentionally fall through.
735  case CUTTING_STRATEGY_ALL:
736  control_parameters[CUTTING_STRATEGY] = value;
737  break;
738  case PIVOT_ROW_STRATEGY_FIRST:
739  // Intentionally fall through.
740  case PIVOT_ROW_STRATEGY_MAX_COLUMN:
741  control_parameters[PIVOT_ROW_STRATEGY] = value;
742  break;
743  default:
744  throw std::invalid_argument("PPL::PIP_Problem::set_control_parameter(v)"
745  ":\ninvalid value.");
746  }
747 }
748 
749 void
751  if (parameters.count(big_dim) == 0) {
752  throw std::invalid_argument("PPL::PIP_Problem::"
753  "set_big_parameter_dimension(big_dim):\n"
754  "dimension 'big_dim' is not a parameter.");
755  }
756  if (big_dim < internal_space_dim) {
757  throw std::invalid_argument("PPL::PIP_Problem::"
758  "set_big_parameter_dimension(big_dim):\n"
759  "only newly-added parameters can be"
760  "converted into the big parameter.");
761  }
762  big_parameter_dimension = big_dim;
763 }
764 
767  memory_size_type n = initial_context.external_memory_in_bytes();
768  // Adding the external memory for `current_solution'.
769  if (current_solution != 0) {
770  n += current_solution->total_memory_in_bytes();
771  }
772  // Adding the external memory for `input_cs'.
773  n += input_cs.capacity() * sizeof(Constraint);
774  for (const_iterator i = input_cs.begin(),
775  i_end = input_cs.end(); i != i_end; ++i) {
776  n += (i->external_memory_in_bytes());
777  }
778  // FIXME: Adding the external memory for `parameters'.
779  n += parameters.size() * sizeof(dimension_type);
780 
781  return n;
782 }
783 
786  return sizeof(*this) + external_memory_in_bytes();
787 }
788 
789 void
790 PPL::PIP_Problem::print_solution(std::ostream& s, int indent) const {
791  switch (status) {
792 
793  case UNSATISFIABLE:
794  PPL_ASSERT(current_solution == 0);
795  PIP_Tree_Node::indent_and_print(s, indent, "_|_\n");
796  break;
797 
798  case OPTIMIZED:
799  PPL_ASSERT(current_solution != 0);
800  current_solution->print(s, indent);
801  break;
802 
803  case PARTIALLY_SATISFIABLE:
804  throw std::logic_error("PIP_Problem::print_solution():\n"
805  "the PIP problem has not been solved.");
806  }
807 }
dimension_type space_dimension() const
Returns the dimension of the smallest vector space enclosing all the variables whose indexes are in t...
dimension_type internal_space_dim
The space dimension of the current (partial) solution of the PIP problem; it may be smaller than exte...
dimension_type max_space_dimension()
Returns the maximum space dimension this library can handle.
static bool compatibility_check(Matrix< Row > &s)
Checks whether a context matrix is satisfiable.
Definition: PIP_Tree.cc:2195
const_iterator constraints_end() const
Returns a past-the-end read-only iterator to the sequence of constraints defining the feasible region...
A linear equality or inequality.
virtual void set_owner(const PIP_Problem *owner)
Sets the pointer to the PIP_Problem owning object.
Definition: PIP_Tree.cc:1120
static dimension_type max_space_dimension()
Returns the maximum space dimension a PIP_Problem can handle.
bool is_equality() const
Returns true if and only if *this is an equality constraint.
void add_constraint(const Constraint &c)
Adds a copy of constraint c to the PIP problem.
Definition: PIP_Problem.cc:697
void set_control_parameter(Control_Parameter_Value value)
Sets control parameter value.
Definition: PIP_Problem.cc:729
virtual void set_owner(const PIP_Problem *owner)
Sets the pointer to the PIP_Problem owning object.
Definition: PIP_Tree.cc:1125
size_t dimension_type
An unsigned integral type for representing space dimensions.
PIP_Problem(dimension_type dim=0)
Builds a trivial PIP problem.
Definition: PIP_Problem.cc:50
An std::set of variables' indexes.
bool ascii_load(std::istream &s)
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this ...
Definition: Constraint.cc:336
void add_constraints(const Constraint_System &cs)
Adds a copy of the constraints in cs to the PIP problem.
Definition: PIP_Problem.cc:713
Enable_If< Is_Native_Or_Checked< T >::value, void >::type ascii_dump(std::ostream &s, const T &t)
virtual void set_owner(const PIP_Problem *owner)=0
Sets the pointer to the PIP_Problem owning object.
dimension_type not_a_dimension()
Returns a value that does not designate a valid dimension.
PIP_Tree_Node * current_solution
The current solution decision tree.
std::ostream & operator<<(std::ostream &s, const Ask_Tell< D > &x)
bool OK() const
Checks if all the invariants are satisfied.
Definition: PIP_Problem.cc:277
A sparse matrix of Coefficient.
Definition: Matrix_defs.hh:37
bool ascii_load(std::istream &is)
Loads from is an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this...
Definition: PIP_Tree.cc:1984
dimension_type space_dimension() const
Returns the dimension of the vector space enclosing *this.
A finite sparse sequence of coefficients.
The standard C++ namespace.
Constraint_Sequence::const_iterator const_iterator
A type alias for the read-only iterator on the constraints defining the feasible region.
dimension_type space_dimension() const
Returns the space dimension of the PIP problem.
An iterator on the tree elements, ordered by key.
const iterator & end()
Returns an iterator that points after the last stored element.
void set_big_parameter_dimension(dimension_type big_dim)
Sets the dimension for the big parameter to big_dim.
Definition: PIP_Problem.cc:750
memory_size_type total_memory_in_bytes() const
Returns the total size in bytes of the memory occupied by *this.
Definition: PIP_Problem.cc:785
const_iterator begin() const
Returns the const_iterator pointing to the first constraint, if *this is not empty; otherwise...
bool all_zeroes_except(const Variables_Set &vars, dimension_type start, dimension_type end) const
Returns true if all coefficients in [start,end), except those corresponding to variables in vars...
memory_size_type external_memory_in_bytes() const
Returns the size in bytes of the memory managed by *this.
Definition: PIP_Problem.cc:766
A Parametric Integer (linear) Programming problem.
virtual PIP_Tree_Node * clone() const =0
Returns a pointer to a dynamically-allocated copy of *this.
Coefficient_traits::const_reference coefficient(Variable v) const
Returns the coefficient of v in *this.
The problem has an optimal solution.
virtual void update_tableau(const PIP_Problem &pip, dimension_type external_space_dim, dimension_type first_pending_constraint, const Constraint_Sequence &input_cs, const Variables_Set &parameters)=0
Populates the parametric simplex tableau using external data.
RA_Container::iterator nth_iter(RA_Container &cont, dimension_type n)
A tree node representing a decision in the space of solutions.
A dimension of the vector space.
void ascii_dump() const
Writes to std::cerr an ASCII representation of *this.
void control_parameters_init()
Initializes the control parameters with default values.
Definition: PIP_Problem.cc:93
bool is_strict_inequality() const
Returns true if and only if *this is a strict inequality constraint.
Control_Parameter_Value control_parameters[CONTROL_PARAMETER_NAME_SIZE]
The control parameters for the problem object.
Control_Parameter_Value
Possible values for PIP_Problem control parameters.
const Variables_Set & parameter_space_dimensions() const
Returns a set containing all the variables' indexes representing the parameters of the PIP problem...
dimension_type first_pending_constraint
The first index of `input_cs' containing a pending constraint.
void ascii_dump(std::ostream &os) const
Dumps to os an ASCII representation of *this.
Definition: PIP_Tree.cc:1909
void control_parameters_copy(const PIP_Problem &y)
Copies the control parameters from problem object y.
Definition: PIP_Problem.cc:99
virtual const PIP_Solution_Node * as_solution() const
Returns this.
Definition: PIP_Tree.cc:1163
Enable_If< Is_Native< T >::value, memory_size_type >::type external_memory_in_bytes(const T &)
For native types, returns the size in bytes of the memory managed by the type of the (unused) paramet...
const_iterator end() const
Returns the past-the-end const_iterator.
Status status
The internal state of the MIP problem.
virtual const PIP_Decision_Node * as_decision() const
Returns this.
Definition: PIP_Tree.cc:1148
Enable_If< Is_Native_Or_Checked< T >::value, bool >::type ascii_load(std::istream &s, T &t)
bool is_satisfiable() const
Checks satisfiability of *this.
Definition: PIP_Problem.cc:721
Coefficient value
Definition: PIP_Tree.cc:618
iterator insert(dimension_type i, Coefficient_traits::const_reference x)
Equivalent to (*this)[i] = x; find(i), but faster.
PIP_Problem_Status
Possible outcomes of the PIP_Problem solver.
void neg_assign(GMP_Integer &x)
#define PPL_OUTPUT_DEFINITIONS(class_name)
The entire library is confined to this namespace.
Definition: version.hh:61
PIP_Problem_Status solve() const
Optimizes the PIP problem.
Definition: PIP_Problem.cc:106
Matrix< Row > initial_context
The initial context.
void clear()
Resets *this to be equal to the trivial PIP problem.
Definition: PIP_Problem.cc:614
PIP_Tree solution() const
Returns a feasible solution for *this, if it exists.
Definition: PIP_Problem.cc:261
static const Constraint & zero_dim_positivity()
The true (zero-dimension space) constraint , also known as positivity constraint. ...
iterator begin()
Returns an iterator that points at the first stored element.
A tree node representing part of the space of solutions.
size_t memory_size_type
An unsigned integral type for representing memory size in bytes.
Coefficient c
Definition: PIP_Tree.cc:64
dimension_type get_big_parameter_dimension() const
Returns the space dimension for the big parameter.
Coefficient_traits::const_reference inhomogeneous_term() const
Returns the inhomogeneous term of *this.
void add_to_parameter_space_dimensions(const Variables_Set &p_vars)
Sets the space dimensions whose indexes which are in set p_vars to be parameter space dimensions...
Definition: PIP_Problem.cc:670
expr_type expression() const
Partial read access to the (adapted) internal expression.
const_iterator constraints_begin() const
Returns a read-only iterator to the first constraint defining the feasible region.
virtual PIP_Tree_Node * solve(const PIP_Problem &pip, bool check_feasible_context, const Matrix< Row > &context, const Variables_Set &params, dimension_type space_dim, int indent_level)=0
Executes a parametric simplex on the tableau, under specified context.
A node of the PIP solution tree.
void add_space_dimensions_and_embed(dimension_type m_vars, dimension_type m_params)
Adds m_vars + m_params new space dimensions and embeds the old PIP problem in the new vector space...
Definition: PIP_Problem.cc:632
void print_solution(std::ostream &s, int indent=0) const
Prints on s the solution computed for *this.
Definition: PIP_Problem.cc:790
bool ascii_load(std::istream &s)
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this ...
Definition: PIP_Tree.cc:1571
PIP_Tree optimizing_solution() const
Returns an optimizing solution for *this, if it exists.
Definition: PIP_Problem.cc:269
static void indent_and_print(std::ostream &s, int indent, const char *str)
A helper function used when printing PIP trees.
Definition: PIP_Tree.cc:3803