1 /* PIP_Tree_Node class declaration.
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 #ifndef PPL_PIP_Tree_defs_hh
25 #define PPL_PIP_Tree_defs_hh 1
26 
27 #include "PIP_Tree_types.hh"
28 #include "Variable_defs.hh"
29 #include "Linear_Expression_types.hh"
30 #include "Constraint_System_defs.hh"
31 #include "Constraint_System_inlines.hh"
32 #include "Constraint_defs.hh"
33 #include "Variables_Set_defs.hh"
34 #include "globals_defs.hh"
35 #include "PIP_Problem_defs.hh"
36 
37 #include "Matrix_defs.hh"
38 #include "Dense_Row_defs.hh"
39 #include "Sparse_Row_defs.hh"
40 
41 namespace Parma_Polyhedra_Library {
42 
43 //! A node of the PIP solution tree.
44 /*!
45   This is the base class for the nodes of the binary trees representing
46   the solutions of PIP problems. From this one, two classes are derived:
47     - PIP_Decision_Node, for the internal nodes of the tree;
48     - PIP_Solution_Node, for the leaves of the tree.
49 */
50 class PIP_Tree_Node {
51 protected:
52   //! Constructor: builds a node owned by \p *owner.
53   explicit PIP_Tree_Node(const PIP_Problem* owner);
54 
55   //! Copy constructor.
56   PIP_Tree_Node(const PIP_Tree_Node& y);
57 
58   //! Returns a pointer to the PIP_Problem owning object.
59   const PIP_Problem* get_owner() const;
60 
61   //! Sets the pointer to the PIP_Problem owning object.
62   virtual void set_owner(const PIP_Problem* owner) = 0;
63 
64   /*! \brief
65     Returns \c true if and only if all the nodes in the subtree
66     rooted in \p *this are owned by \p *owner.
67   */
68   virtual bool check_ownership(const PIP_Problem* owner) const = 0;
69 
70 public:
71 #if PPL_USE_SPARSE_MATRIX
72   typedef Sparse_Row Row;
73 #else
74   typedef Dense_Row Row;
75 #endif
76 
77   //! Returns a pointer to a dynamically-allocated copy of \p *this.
78   virtual PIP_Tree_Node* clone() const = 0;
79 
80   //! Destructor.
81   virtual ~PIP_Tree_Node();
82 
83   //! Returns \c true if and only if \p *this is well formed.
84   virtual bool OK() const = 0;
85 
86   //! Returns \p this if \p *this is a solution node, 0 otherwise.
87   virtual const PIP_Solution_Node* as_solution() const = 0;
88 
89   //! Returns \p this if \p *this is a decision node, 0 otherwise.
90   virtual const PIP_Decision_Node* as_decision() const = 0;
91 
92   /*! \brief
93     Returns the system of parameter constraints controlling \p *this.
94 
95     The indices in the constraints are the same as the original variables and
96     parameters. Coefficients in indices corresponding to variables always are
97     zero.
98   */
99   const Constraint_System& constraints() const;
100 
101   class Artificial_Parameter;
102 
103   //! A type alias for a sequence of Artificial_Parameter's.
104   typedef std::vector<Artificial_Parameter> Artificial_Parameter_Sequence;
105 
106   //! Returns a const_iterator to the beginning of local artificial parameters.
107   Artificial_Parameter_Sequence::const_iterator art_parameter_begin() const;
108 
109   //! Returns a const_iterator to the end of local artificial parameters.
110   Artificial_Parameter_Sequence::const_iterator art_parameter_end() const;
111 
112   //! Returns the number of local artificial parameters.
113   dimension_type art_parameter_count() const;
114 
115   //! Prints on \p s the tree rooted in \p *this.
116   /*!
117     \param s
118     The output stream.
119 
120     \param indent
121     The amount of indentation.
122   */
123   void print(std::ostream& s, int indent = 0) const;
124 
125   //! Dumps to \p s an ASCII representation of \p *this.
126   void ascii_dump(std::ostream& s) const;
127 
128   /*! \brief
129     Loads from \p s an ASCII representation (as produced by
130     ascii_dump(std::ostream&) const) and sets \p *this accordingly.
131     Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise.
132   */
133   bool ascii_load(std::istream& s);
134 
135   //! Returns the total size in bytes of the memory occupied by \p *this.
136   virtual memory_size_type total_memory_in_bytes() const = 0;
137   //! Returns the size in bytes of the memory managed by \p *this.
138   virtual memory_size_type external_memory_in_bytes() const = 0;
139 
140 protected:
141   //! A type alias for a sequence of constraints.
142   typedef std::vector<Constraint> Constraint_Sequence;
143 
144   // Only PIP_Problem and PIP_Decision_Node are allowed to use the
145   // constructor and methods.
146   friend class PIP_Problem;
147   friend class PIP_Decision_Node;
148   friend class PIP_Solution_Node;
149 
150   //! A pointer to the PIP_Problem object owning this node.
151   const PIP_Problem* owner_;
152 
153   //! A pointer to the parent of \p *this, null if \p *this is the root.
154   const PIP_Decision_Node* parent_;
155 
156   //! The local system of parameter constraints.
157   Constraint_System constraints_;
158 
159   //! The local sequence of expressions for local artificial parameters.
160   Artificial_Parameter_Sequence artificial_parameters;
161 
162   //! Returns a pointer to this node's parent.
163   const PIP_Decision_Node* parent() const;
164 
165   //! Set this node's parent to \p *p.
166   void set_parent(const PIP_Decision_Node* p);
167 
168   /*! \brief
169     Populates the parametric simplex tableau using external data.
170 
171     \param pip
172     The PIP_Problem object containing this node.
173 
174     \param external_space_dim
175     The number of all problem variables and problem parameters
176     (excluding artificial parameters).
177 
178     \param first_pending_constraint
179     The first element in \p input_cs to be added to the tableau,
180     which already contains the previous elements.
181 
182     \param input_cs
183     All the constraints of the PIP problem.
184 
185     \param parameters
186     The set of indices of the problem parameters.
187   */
188   virtual void update_tableau(const PIP_Problem& pip,
189                               dimension_type external_space_dim,
190                               dimension_type first_pending_constraint,
191                               const Constraint_Sequence& input_cs,
192                               const Variables_Set& parameters) = 0;
193 
194   /*! \brief
195     Executes a parametric simplex on the tableau, under specified context.
196 
197     \return
198     The root of the PIP tree solution, or 0 if unfeasible.
199 
200     \param pip
201     The PIP_Problem object containing this node.
202 
203     \param check_feasible_context
204     Whether the resolution process should (re-)check feasibility of
205     context (since the initial context may have been modified).
206 
207     \param context
208     The context, being a set of constraints on the parameters.
209 
210     \param params
211     The local parameter set, including parent's artificial parameters.
212 
213     \param space_dim
214     The space dimension of parent, including artificial parameters.
215 
216     \param indent_level
217     The indentation level (for debugging output only).
218   */
219   virtual PIP_Tree_Node* solve(const PIP_Problem& pip,
220                                bool check_feasible_context,
221                                const Matrix<Row>& context,
222                                const Variables_Set& params,
223                                dimension_type space_dim,
224                                int indent_level) = 0;
225 
226   //! Inserts a new parametric constraint in internal row format.
227   void add_constraint(const Row& row, const Variables_Set& parameters);
228 
229   //! Merges parent's artificial parameters into \p *this.
230   void parent_merge();
231 
232   //! Prints on \p s the tree rooted in \p *this.
233   /*!
234     \param s
235     The output stream.
236 
237     \param indent
238     The amount of indentation.
239 
240     \param pip_dim_is_param
241     A vector of Boolean flags telling which PIP problem dimensions are
242     problem parameters. The size of the vector is equal to the PIP
243     problem internal space dimension (i.e., no artificial parameters).
244 
245     \param first_art_dim
246     The first space dimension corresponding to an artificial parameter
247     that was created in this node (if any).
248   */
249   virtual void print_tree(std::ostream& s,
250                           int indent,
251                           const std::vector<bool>& pip_dim_is_param,
252                           dimension_type first_art_dim) const = 0;
253 
254   //! A helper function used when printing PIP trees.
255   static void
256   indent_and_print(std::ostream& s, int indent, const char* str);
257 
258   /*! \brief
259     Checks whether a context matrix is satisfiable.
260 
261     The satisfiability check is implemented by the revised dual simplex
262     algorithm on the context matrix. The algorithm ensures the feasible
263     solution is integer by applying a cut generation method when
264     intermediate non-integer solutions are found.
265   */
266   static bool compatibility_check(Matrix<Row>& s);
267 
268   /*! \brief
269     Helper method: checks for satisfiability of the restricted context
270     obtained by adding \p row to \p context.
271   */
272   static bool compatibility_check(const Matrix<Row>& context, const Row& row);
273 
274 }; // class PIP_Tree_Node
275 
276 
277 /*! \brief
278   Artificial parameters in PIP solution trees.
279 
280   These parameters are built from a linear expression combining other
281   parameters (constant term included) divided by a positive integer
282   denominator. Coefficients at variables indices corresponding to
283   PIP problem variables are always zero.
284 */
285 class PIP_Tree_Node::Artificial_Parameter
286   : public Linear_Expression {
287 public:
288   //! Default constructor: builds a zero artificial parameter.
289   Artificial_Parameter();
290 
291   //! Constructor.
292   /*!
293     Builds artificial parameter \f$\frac{\mathtt{expr}}{\mathtt{d}}\f$.
294 
295     \param expr
296     The expression that, after normalization, will form the numerator of
297     the artificial parameter.
298 
299     \param d
300     The integer constant that, after normalization, will form the
301     denominator of the artificial parameter.
302 
303     \exception std::invalid_argument
304     Thrown if \p d is zero.
305 
306     Normalization will ensure that the denominator is positive.
307   */
308   Artificial_Parameter(const Linear_Expression& expr,
309                        Coefficient_traits::const_reference d);
310 
311   //! Copy constructor.
312   Artificial_Parameter(const Artificial_Parameter& y);
313 
314   //! Returns the normalized (i.e., positive) denominator.
315   Coefficient_traits::const_reference denominator() const;
316 
317   //! Swaps \p *this with \p y.
318   void m_swap(Artificial_Parameter& y);
319 
320   //! Returns \c true if and only if \p *this and \p y are equal.
321   /*!
322     Note that two artificial parameters having different space dimensions
323     are considered to be different.
324   */
325   bool operator==(const Artificial_Parameter& y) const;
326   //! Returns \c true if and only if \p *this and \p y are different.
327   bool operator!=(const Artificial_Parameter& y) const;
328 
329   PPL_OUTPUT_DECLARATIONS
330 
331   /*! \brief
332     Loads from \p s an ASCII representation (as produced by
333     ascii_dump(std::ostream&) const) and sets \p *this accordingly.
334     Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise.
335   */
336   bool ascii_load(std::istream& s);
337 
338   //! Returns the total size in bytes of the memory occupied by \p *this.
339   memory_size_type total_memory_in_bytes() const;
340   //! Returns the size in bytes of the memory managed by \p *this.
341   memory_size_type external_memory_in_bytes() const;
342 
343   //! Returns \c true if and only if the parameter is well-formed.
344   bool OK() const;
345 
346 private:
347   //! The normalized (i.e., positive) denominator.
348   Coefficient denom;
349 }; // class PIP_Tree_Node::Artificial_Parameter
350 
351 
352 //! Swaps \p x with \p y.
353 /*! \relates PIP_Tree_Node::Artificial_Parameter */
354 void
355 swap(PIP_Tree_Node::Artificial_Parameter& x,
356      PIP_Tree_Node::Artificial_Parameter& y);
357 
358 
359 //! A tree node representing part of the space of solutions.
360 class PIP_Solution_Node : public PIP_Tree_Node {
361 public:
362 
363   //! Constructor: builds a solution node owned by \p *owner.
364   explicit PIP_Solution_Node(const PIP_Problem* owner);
365 
366   //! Returns a pointer to a dynamically-allocated copy of \p *this.
367   virtual PIP_Tree_Node* clone() const;
368 
369   //! Destructor.
370   virtual ~PIP_Solution_Node();
371 
372   //! Returns \c true if and only if \p *this is well formed.
373   virtual bool OK() const;
374 
375   //! Returns \p this.
376   virtual const PIP_Solution_Node* as_solution() const;
377 
378   //! Returns 0, since \p this is not a decision node.
379   virtual const PIP_Decision_Node* as_decision() const;
380 
381   /*! \brief
382     Returns a parametric expression for the values of problem variable \p var.
383 
384     The returned linear expression may involve problem parameters
385     as well as artificial parameters.
386 
387     \param var
388     The problem variable which is queried about.
389 
390     \exception std::invalid_argument
391     Thrown if \p var is dimension-incompatible with the PIP_Problem
392     owning this solution node, or if \p var is a problem parameter.
393   */
394   const Linear_Expression& parametric_values(Variable var) const;
395 
396   //! Dumps to \p os an ASCII representation of \p *this.
397   void ascii_dump(std::ostream& os) const;
398 
399   /*! \brief
400     Loads from \p is an ASCII representation (as produced by
401     ascii_dump(std::ostream&) const) and sets \p *this accordingly.
402     Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise.
403   */
404   bool ascii_load(std::istream& is);
405 
406   //! Returns the total size in bytes of the memory occupied by \p *this.
407   virtual memory_size_type total_memory_in_bytes() const;
408   //! Returns the size in bytes of the memory managed by \p *this.
409   virtual memory_size_type external_memory_in_bytes() const;
410 
411 private:
412   //! The type for parametric simplex tableau.
413   struct Tableau {
414     //! The matrix of simplex coefficients.
415     Matrix<Row> s;
416     //! The matrix of parameter coefficients.
417     Matrix<Row> t;
418     //! A common denominator for all matrix elements
419     Coefficient denom;
420 
421     //! Default constructor.
422     Tableau();
423     //! Copy constructor.
424     Tableau(const Tableau& y);
425     //! Destructor.
426     ~Tableau();
427 
428     //! Tests whether the matrix is integer, i.e., the denominator is 1.
429     bool is_integer() const;
430 
431     //! Multiplies all coefficients and denominator with ratio.
432     void scale(Coefficient_traits::const_reference ratio);
433 
434     //! Normalizes the modulo of coefficients so that they are mutually prime.
435     /*!
436       Computes the Greatest Common Divisor (GCD) among the elements of
437       the matrices and normalizes them and the denominator by the GCD itself.
438     */
439     void normalize();
440 
441     /*! \brief
442       Compares two pivot row and column pairs before pivoting.
443 
444       The algorithm searches the first (ie, leftmost) column \f$k\f$ in
445       parameter matrix for which the \f$c=s_{*j}\frac{t_{ik}}{s_{ij}}\f$
446       and \f$c'=s_{*j'}\frac{t_{i'k}}{s_{i'j'}}\f$ columns are different,
447       where \f$s_{*j}\f$ denotes the \f$j\f$<sup>th</sup> column from the
448       \f$s\f$ matrix and \f$s_{*j'}\f$ is the \f$j'\f$<sup>th</sup> column
449       of \f$s\f$.
450 
451       \f$c\f$ is the computed column that would be subtracted to column
452       \f$k\f$ in parameter matrix if pivoting is done using the \f$(i,j)\f$
453       row and column pair.
454       \f$c'\f$ is the computed column that would be subtracted to column
455       \f$k\f$ in parameter matrix if pivoting is done using the
456       \f$(i',j')\f$ row and column pair.
457 
458       The test is true if the computed \f$-c\f$ column is lexicographically
459       bigger than the \f$-c'\f$ column. Due to the column ordering in the
460       parameter matrix of the tableau, leftmost search will enforce solution
461       increase with respect to the following priority order:
462        - the constant term
463        - the coefficients for the original parameters
464        - the coefficients for the oldest artificial parameters.
465 
466       \return
467       \c true if pivot row and column pair \f$(i,j)\f$ is more
468       suitable for pivoting than the \f$(i',j')\f$ pair
469 
470       \param mapping
471       The PIP_Solution_Node::mapping vector for the tableau.
472 
473       \param basis
474       The PIP_Solution_Node::basis vector for the tableau.
475 
476       \param row_0
477       The row number for the first pivot row and column pair to be compared.
478 
479       \param col_0
480       The column number for the first pivot row and column pair to be
481       compared.
482 
483       \param row_1
484       The row number for the second pivot row and column pair to be compared.
485 
486       \param col_1
487       The column number for the second pivot row and column pair to be
488       compared.
489     */
490     bool is_better_pivot(const std::vector<dimension_type>& mapping,
491                          const std::vector<bool>& basis,
492                          const dimension_type row_0,
493                          const dimension_type col_0,
494                          const dimension_type row_1,
495                          const dimension_type col_1) const;
496 
497     //! Returns the value of the denominator.
498     Coefficient_traits::const_reference denominator() const;
499 
500     //! Dumps to \p os an ASCII representation of \p *this.
501     void ascii_dump(std::ostream& os) const;
502 
503     /*! \brief
504       Loads from \p is an ASCII representation (as produced by
505       ascii_dump(std::ostream&) const) and sets \p *this accordingly.
506       Returns \c true if successful, \c false otherwise.
507     */
508     bool ascii_load(std::istream& is);
509 
510     //! Returns the size in bytes of the memory managed by \p *this.
511     /*!
512       \note
513       No need for a \c total_memory_in_bytes() method, since
514       class Tableau is a private inner class of PIP_Solution_Node.
515     */
516     memory_size_type external_memory_in_bytes() const;
517 
518     //! Returns \c true if and only if \p *this is well formed.
519     bool OK() const;
520   }; // struct Tableau
521 
522   //! The parametric simplex tableau.
523   Tableau tableau;
524 
525   /*! \brief
526     A boolean vector for identifying the basic variables.
527 
528     Variable identifiers are numbered from 0 to <CODE>n+m-1</CODE>, where \p n
529     is the number of columns in the simplex tableau corresponding to variables,
530     and \p m is the number of rows.
531 
532     Indices from 0 to <CODE>n-1</CODE> correspond to the original variables.
533 
534     Indices from \p n to <CODE>n+m-1</CODE> correspond to the slack variables
535     associated to the internal constraints, which do not strictly correspond
536     to original constraints, since these may have been transformed to fit the
537     standard form of the dual simplex.
538 
539     The value for <CODE>basis[i]</CODE> is:
540      - \b true if variable \p i is basic,
541      - \b false if variable \p i is nonbasic.
542   */
543   std::vector<bool> basis;
544 
545   /*! \brief
546     A mapping between the tableau rows/columns and the original variables.
547 
548     The value of <CODE>mapping[i]</CODE> depends of the value of <CODE>basis[i]</CODE>.
549 
550      - If <CODE>basis[i]</CODE> is \b true, <CODE>mapping[i]</CODE> encodes the column
551        index of variable \p i in the \p s matrix of the tableau.
552      - If <CODE>basis[i]</CODE> is \b false, <CODE>mapping[i]</CODE> encodes the row
553        index of variable \p i in the tableau.
554   */
555   std::vector<dimension_type> mapping;
556 
557   /*! \brief
558     The variable identifiers associated to the rows of the simplex tableau.
559   */
560   std::vector<dimension_type> var_row;
561 
562   /*! \brief
563     The variable identifiers associated to the columns of the simplex tableau.
564   */
565   std::vector<dimension_type> var_column;
566 
567   /*! \brief
568     The variable number of the special inequality used for modeling
569     equality constraints.
570 
571     The subset of equality constraints in a specific problem can be expressed
572     as: \f$f_i(x,p) = 0 ; 1 \leq i \leq n\f$. As the dual simplex standard form
573     requires constraints to be inequalities, the following constraints can be
574     modeled as follows:
575 
576      - \f$f_i(x,p) \geq 0 ; 1 \leq i \leq n\f$
577 
578      - \f$\sum\limits_{i=1}^n f_i(x,p) \leq 0\f$
579 
580     The \p special_equality_row value stores the variable number of the
581     specific constraint which is used to model the latter sum of
582     constraints. If no such constraint exists, the value is set to \p 0.
583   */
584   dimension_type special_equality_row;
585 
586   /*! \brief
587     The column index in the parametric part of the simplex tableau
588     corresponding to the big parameter; \c not_a_dimension() if not set.
589   */
590   dimension_type big_dimension;
591 
592   //! The possible values for the sign of a parametric linear expression.
593   enum Row_Sign {
594     //! Not computed yet (default).
595     UNKNOWN,
596     //! All row coefficients are zero.
597     ZERO,
598     //! All nonzero row coefficients are positive.
599     POSITIVE,
600     //! All nonzero row coefficients are negative.
601     NEGATIVE,
602     //! The row contains both positive and negative coefficients.
603     MIXED
604   };
605 
606   //! A cache for computed sign values of constraint parametric RHS.
607   std::vector<Row_Sign> sign;
608 
609   //! Parametric values for the solution.
610   std::vector<Linear_Expression> solution;
611 
612   //! An indicator for solution validity.
613   bool solution_valid;
614 
615   //! Returns the sign of row \p x.
616   static Row_Sign row_sign(const Row& x,
617                            dimension_type big_dimension);
618 
619 protected:
620   //! Copy constructor.
621   PIP_Solution_Node(const PIP_Solution_Node& y);
622 
623   //! A tag type to select the alternative copy constructor.
624   struct No_Constraints {};
625 
626   //! Alternative copy constructor.
627   /*!
628     This constructor differs from the default copy constructor in that
629     it will not copy the constraint system, nor the artificial parameters.
630   */
631   PIP_Solution_Node(const PIP_Solution_Node& y, No_Constraints);
632 
633   // PIP_Problem::ascii load() method needs access set_owner().
634   friend bool PIP_Problem::ascii_load(std::istream& s);
635 
636   //! Sets the pointer to the PIP_Problem owning object.
637   virtual void set_owner(const PIP_Problem* owner);
638 
639   /*! \brief
640     Returns \c true if and only if all the nodes in the subtree
641     rooted in \p *this is owned by \p *pip.
642   */
643   virtual bool check_ownership(const PIP_Problem* owner) const;
644 
645   //! Implements pure virtual method PIP_Tree_Node::update_tableau.
646   virtual void update_tableau(const PIP_Problem& pip,
647                               dimension_type external_space_dim,
648                               dimension_type first_pending_constraint,
649                               const Constraint_Sequence& input_cs,
650                               const Variables_Set& parameters);
651 
652   /*! \brief
653     Update the solution values.
654 
655     \param pip_dim_is_param
656     A vector of Boolean flags telling which PIP problem dimensions are
657     problem parameters. The size of the vector is equal to the PIP
658     problem internal space dimension (i.e., no artificial parameters).
659   */
660   void update_solution(const std::vector<bool>& pip_dim_is_param) const;
661 
662   //! Helper method.
663   void update_solution() const;
664 
665   //! Implements pure virtual method PIP_Tree_Node::solve.
666   virtual PIP_Tree_Node* solve(const PIP_Problem& pip,
667                                bool check_feasible_context,
668                                const Matrix<Row>& context,
669                                const Variables_Set& params,
670                                dimension_type space_dim,
671                                int indent_level);
672 
673   /*! \brief
674     Generate a Gomory cut using non-integer tableau row \p index.
675 
676     \param index
677     Row index in simplex tableau from which the cut is generated.
678 
679     \param parameters
680     A std::set of the current parameter dimensions (including artificials);
681     to be updated if a new artificial parameter is to be created.
682 
683     \param context
684     A set of linear inequalities on the parameters, in matrix form; to be
685     updated if a new artificial parameter is to be created.
686 
687     \param space_dimension
688     The current space dimension, including variables and all parameters; to
689     be updated if an extra parameter is to be created.
690 
691     \param indent_level
692     The indentation level (for debugging output only).
693   */
694   void generate_cut(dimension_type index, Variables_Set& parameters,
695                     Matrix<Row>& context, dimension_type& space_dimension,
696                     int indent_level);
697 
698   //! Prints on \p s the tree rooted in \p *this.
699   virtual void print_tree(std::ostream& s, int indent,
700                           const std::vector<bool>& pip_dim_is_param,
701                           dimension_type first_art_dim) const;
702 
703 }; // class PIP_Solution_Node
704 
705 
706 //! A tree node representing a decision in the space of solutions.
707 class PIP_Decision_Node : public PIP_Tree_Node {
708 public:
709   //! Returns a pointer to a dynamically-allocated copy of \p *this.
710   virtual PIP_Tree_Node* clone() const;
711 
712   //! Destructor.
713   virtual ~PIP_Decision_Node();
714 
715   //! Returns \c true if and only if \p *this is well formed.
716   virtual bool OK() const;
717 
718   //! Returns \p this.
719   virtual const PIP_Decision_Node* as_decision() const;
720 
721   //! Returns 0, since \p this is not a solution node.
722   virtual const PIP_Solution_Node* as_solution() const;
723 
724   //! Returns a const pointer to the \p b (true or false) branch of \p *this.
725   const PIP_Tree_Node* child_node(bool b) const;
726 
727   //! Returns a pointer to the \p b (true or false) branch of \p *this.
728   PIP_Tree_Node* child_node(bool b);
729 
730   //! Dumps to \p s an ASCII representation of \p *this.
731   void ascii_dump(std::ostream& s) const;
732 
733   /*! \brief
734     Loads from \p s an ASCII representation (as produced by
735     ascii_dump(std::ostream&) const) and sets \p *this accordingly.
736     Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise.
737   */
738   bool ascii_load(std::istream& s);
739 
740   //! Returns the total size in bytes of the memory occupied by \p *this.
741   virtual memory_size_type total_memory_in_bytes() const;
742   //! Returns the size in bytes of the memory managed by \p *this.
743   virtual memory_size_type external_memory_in_bytes() const;
744 
745 private:
746   // PIP_Solution_Node is allowed to use the constructor and methods.
747   friend class PIP_Solution_Node;
748 
749   // PIP_Problem ascii load method needs access to private constructors.
750   friend bool PIP_Problem::ascii_load(std::istream& s);
751 
752   //! Pointer to the "false" child of \p *this.
753   PIP_Tree_Node* false_child;
754 
755   //! Pointer to the "true" child of \p *this.
756   PIP_Tree_Node* true_child;
757 
758   /*! \brief
759     Builds a decision node having \p fcp and \p tcp as child.
760 
761     The decision node will encode the structure
762     "if \c cs then \p tcp else \p fcp",
763     where the system of constraints \c cs is initially empty.
764 
765     \param owner
766     Pointer to the owning PIP_Problem object; it may be null if and
767     only if both children are null.
768 
769     \param fcp
770     Pointer to "false" child; it may be null.
771 
772     \param tcp
773     Pointer to "true" child; it may be null.
774 
775     \note
776     If any of \p fcp or \p tcp is not null, then \p owner is required
777     to be not null and equal to the owner of its non-null children;
778     otherwise the behavior is undefined.
779   */
780   explicit PIP_Decision_Node(const PIP_Problem* owner,
781                              PIP_Tree_Node* fcp,
782                              PIP_Tree_Node* tcp);
783 
784   //! Sets the pointer to the PIP_Problem owning object.
785   virtual void set_owner(const PIP_Problem* owner);
786 
787   /*! \brief
788     Returns \c true if and only if all the nodes in the subtree
789     rooted in \p *this is owned by \p *pip.
790   */
791   virtual bool check_ownership(const PIP_Problem* owner) const;
792 
793 protected:
794   //! Copy constructor.
795   PIP_Decision_Node(const PIP_Decision_Node& y);
796 
797   //! Implements pure virtual method PIP_Tree_Node::update_tableau.
798   virtual void update_tableau(const PIP_Problem& pip,
799                               dimension_type external_space_dim,
800                               dimension_type first_pending_constraint,
801                               const Constraint_Sequence& input_cs,
802                               const Variables_Set& parameters);
803 
804   //! Implements pure virtual method PIP_Tree_Node::solve.
805   virtual PIP_Tree_Node* solve(const PIP_Problem& pip,
806                                bool check_feasible_context,
807                                const Matrix<Row>& context,
808                                const Variables_Set& params,
809                                dimension_type space_dim,
810                                int indent_level);
811 
812   //! Prints on \p s the tree rooted in \p *this.
813   virtual void print_tree(std::ostream& s, int indent,
814                           const std::vector<bool>& pip_dim_is_param,
815                           dimension_type first_art_dim) const;
816 
817 }; // class PIP_Decision_Node
818 
819 namespace IO_Operators {
820 
821 //! Output operator: prints the solution tree rooted in \p x.
822 /*! \relates Parma_Polyhedra_Library::PIP_Tree_Node */
823 std::ostream& operator<<(std::ostream& os, const PIP_Tree_Node& x);
824 
825 //! Output operator.
826 /*! \relates Parma_Polyhedra_Library::PIP_Tree_Node::Artificial_Parameter */
827 std::ostream& operator<<(std::ostream& os,
828                          const PIP_Tree_Node::Artificial_Parameter& x);
829 
830 } // namespace IO_Operators
831 
832 } // namespace Parma_Polyhedra_Library
833 
834 #include "PIP_Tree_inlines.hh"
835 
836 #endif // !defined(PPL_PIP_Tree_defs_hh)
837