1 /* $Id$
2  *
3  * Name:    exprOp.hpp
4  * Author:  Pietro Belotti
5  * Purpose: definition of the n-ary expression class
6  *
7  * (C) Carnegie-Mellon University, 2006-08.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #ifndef COUENNE_EXPROP_HPP
12 #define COUENNE_EXPROP_HPP
13 
14 #include <iostream>
15 
16 #include "CouenneExpression.hpp"
17 #include "CouenneTypes.hpp"
18 
19 namespace Couenne {
20 
21 #define MAX_ARG_LINE 10
22 
23 class CouenneProblem;
24 class Domain;
25 
26 /// general n-ary operator-type expression: requires argument
27 /// list. All non-unary and non-leaf operators, i.e., sum,
28 /// subtraction, multiplication, power, division, max, min, etc. are
29 /// derived from this class.
30 
31 class exprOp: public expression {
32 
33  protected:
34 
35   expression **arglist_; ///< argument list is an array of pointers to other expressions
36   int          nargs_;   ///< number of arguments (cardinality of arglist)
37 
38  public:
39 
40   /// Node type
Type() const41   virtual inline enum nodeType Type () const
42     {return N_ARY;}
43 
44   /// Constructor
exprOp(expression ** arglist,int nargs)45   exprOp (expression **arglist, int nargs):  //< non-leaf expression, with argument list
46     arglist_ (arglist),
47     nargs_   (nargs)
48     {}
49 
50   /// Constructor with two arguments (for convenience)
exprOp(expression * arg0,expression * arg1)51   exprOp (expression *arg0, expression *arg1):  //< two arguments
52     arglist_ (new expression * [2]),
53     nargs_   (2)
54     {arglist_ [0] = arg0; arglist_ [1] = arg1;}
55 
56   /// Destructor
57   virtual ~exprOp ();
58 
59   /// Copy constructor: only allocate space for argument list, which
60   /// will be copied with clonearglist()
exprOp(const exprOp & e,Domain * d=NULL)61   exprOp (const exprOp &e, Domain *d = NULL):
62     arglist_ (new expression * [e.nArgs ()]),
63     nargs_   (e.nArgs ()) {}
64 
65   /// return argument list
ArgList() const66   inline expression **ArgList () const
67   {return arglist_;}
68 
69   /// set arglist (used in deleting nodes without deleting children)
ArgList(expression ** al)70   virtual inline void ArgList (expression **al)
71   {arglist_ = al;}
72 
73   /// return number of arguments
nArgs() const74   inline int nArgs () const
75   {return nargs_;}
76 
77   /// I/O
78   virtual void print (std::ostream &out = std::cout,
79 		      bool = false) const;
80 
81   /// print position (PRE, INSIDE, POST)
printPos() const82   virtual enum pos printPos () const
83   {return INSIDE;}
84 
85   /// print operator
printOp() const86   virtual std::string printOp () const
87   {return "??";}
88 
89   /// fill in the set with all indices of variables appearing in the
90   /// expression
91   virtual int DepList (std::set <int> &deplist, enum dig_type type = ORIG_ONLY);
92 
93   /// simplification
94   virtual expression *simplify ();
95 
96   /// clone argument list (for use with clone method)
clonearglist(Domain * d=NULL) const97   expression **clonearglist (Domain *d = NULL) const {
98     if (nargs_) {
99       expression **al = new expression * [nargs_];
100       for (register int i=0; i<nargs_; i++)
101 	al [i] = arglist_ [i] -> clone (d);
102       return al;
103     } else return NULL;
104   }
105 
106   /// compress argument list
107   int shrink_arglist (CouNumber, CouNumber);
108 
109   /// get a measure of "how linear" the expression is (see CouenneTypes.h)
Linearity()110   virtual inline int Linearity ()
111   {return NONLINEAR;}
112 
113   /// generate auxiliary variable
114   virtual exprAux *standardize (CouenneProblem *, bool addAux = true);
115 
116   /// return code to classify type of expression
code()117   virtual inline enum expr_type code ()
118   {return COU_EXPROP;}
119 
120   /// is this expression integer?
121   virtual bool isInteger ();
122 
123   /// compare with other generic exprOp
124   virtual int compare (exprOp &);
125 
126   /// used in rank-based branching variable choice
127   virtual int rank ();
128 
129   /// fill in dependence structure
130   /// update dependence set with index of this variable
fillDepSet(std::set<DepNode *,compNode> * dep,DepGraph * g)131   virtual void fillDepSet (std::set <DepNode *, compNode> *dep, DepGraph *g) {
132     for (int i=nargs_; i--;)
133       arglist_ [i] -> fillDepSet (dep, g);
134   }
135 
136   /// replace variable with other
137   virtual void replace (exprVar *, exprVar *);
138 
139   /// empty function to redirect variables to proper variable vector
140   virtual void realign (const CouenneProblem *p);
141 };
142 
143 }
144 
145 #endif
146