- modified the comment blocks so the copyright message no longer appears in
[ginac.git] / ginac / ex.h
1 /** @file ex.h
2  *
3  *  Interface to GiNaC's light-weight expression handles. */
4
5 /*
6  *  GiNaC Copyright (C) 1999 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #ifndef __GINAC_EX_H__
24 #define __GINAC_EX_H__
25
26 #include <iostream>
27 #include <ginac/basic.h>
28 #include <ginac/operators.h>
29
30 class ex;
31 class expand_options;
32 class status_flags;
33
34 class symbol;
35 class lst;
36
37 typedef vector<ex> exvector;
38
39 // enum definitions
40
41 ex const & exZERO(void);
42 ex const & exONE(void);
43 ex const & exTWO(void);
44 ex const & exTHREE(void);
45 ex const & exMINUSONE(void);
46 ex const & exHALF(void);
47 ex const & exMINUSHALF(void);
48
49 #define INLINE_EX_CONSTRUCTORS
50
51 /** Lightweight interface to GiNaC's symbolic objects. Basically all it does is
52  *  to hold a pointer to the other objects, manage the reference counting and
53  *  provide methods for manipulation of these objects. */
54 class ex
55 {
56     friend class basic;
57
58 // member functions
59
60     // default constructor, destructor, copy constructor assignment operator and helpers
61 public:
62     ex()
63 #ifdef INLINE_EX_CONSTRUCTORS
64     : bp(exZERO().bp)
65         {
66             debugmsg("ex default constructor",LOGLEVEL_CONSTRUCT);
67             ASSERT(exZERO().bp!=0);
68             ASSERT(exZERO().bp->flags & status_flags::dynallocated);
69             ASSERT(bp!=0);
70             ++bp->refcount;
71         }
72 #else
73 ;
74 #endif // def INLINE_EX_CONSTRUCTORS
75
76     ~ex()
77 #ifdef INLINE_EX_CONSTRUCTORS
78         {
79             debugmsg("ex destructor",LOGLEVEL_DESTRUCT);
80             ASSERT(bp!=0);
81             ASSERT(bp->flags & status_flags::dynallocated);
82             if (--bp->refcount == 0) {
83                 delete bp;
84             }
85         }
86 #else
87 ;
88 #endif // def INLINE_EX_CONSTRUCTORS
89         
90     ex(ex const & other)
91 #ifdef INLINE_EX_CONSTRUCTORS
92     : bp(other.bp)
93         {
94             debugmsg("ex copy constructor",LOGLEVEL_CONSTRUCT);
95             ASSERT(bp!=0);
96             ASSERT((bp->flags) & status_flags::dynallocated);
97             ++bp->refcount;
98         }
99 #else
100 ;
101 #endif // def INLINE_EX_CONSTRUCTORS
102         
103     ex const & operator=(ex const & other)
104 #ifdef INLINE_EX_CONSTRUCTORS
105         {
106             debugmsg("ex operator=",LOGLEVEL_ASSIGNMENT);
107             ASSERT(bp!=0);
108             ASSERT(bp->flags & status_flags::dynallocated);
109             ASSERT(other.bp!=0);
110             ASSERT(other.bp->flags & status_flags::dynallocated);
111             ++other.bp->refcount;
112             basic * tmpbp=other.bp;
113             if (--bp->refcount==0) {
114                 delete bp;
115             }
116             bp=tmpbp;
117             return *this;
118         }
119 #else
120 ;
121 #endif // def INLINE_EX_CONSTRUCTORS
122
123     // other constructors
124 public:
125     ex(basic const & other)
126 #ifdef INLINE_EX_CONSTRUCTORS
127     {
128         debugmsg("ex constructor from basic",LOGLEVEL_CONSTRUCT);
129         construct_from_basic(other);
130     }
131 #else
132 ;
133 #endif // def INLINE_EX_CONSTRUCTORS
134     
135     ex(int const i);
136     ex(unsigned int const i);
137     ex(long const i);
138     ex(unsigned long const i);
139     ex(double const d);
140
141     // functions overriding virtual functions from bases classes
142     // none
143     
144     // new virtual functions which can be overridden by derived classes
145     // none
146
147     // non-virtual functions in this class
148 public:
149     void swap(ex & other);
150     void printraw(ostream & os) const;
151     void printtree(ostream & os, unsigned indent=0) const;
152     void print(ostream & os, unsigned upper_precedence=0) const;
153     void printcsrc(ostream & os, unsigned type, const char *var_name) const;
154     void dbgprint(void) const;
155     void dbgprinttree(void) const;
156     bool info(unsigned inf) const;
157     int nops() const;
158     ex expand(unsigned options=0) const;
159     bool has(ex const & other) const;
160     int degree(symbol const & s) const;
161     int ldegree(symbol const & s) const;
162     ex coeff(symbol const & s, int const n=1) const;
163     ex lcoeff(symbol const & s) const { return coeff(s, degree(s)); }
164     ex tcoeff(symbol const & s) const { return coeff(s, ldegree(s)); }
165     ex numer(bool normalize = true) const;
166     ex denom(bool normalize = true) const;
167     ex unit(const symbol &x) const;
168     ex content(const symbol &x) const;
169     numeric integer_content(void) const;
170     ex primpart(const symbol &x) const;
171     ex primpart(const symbol &x, const ex &cont) const;
172     ex normal(int level = 0) const;
173     ex smod(const numeric &xi) const;
174     numeric max_coefficient(void) const;
175     ex collect(symbol const & s) const;
176     ex eval(int level = 0) const;
177     ex evalf(int level = 0) const;
178     ex diff(symbol const & s, unsigned nth = 1) const;
179     ex series(symbol const & s, ex const & point, int order = 6) const;
180     ex subs(lst const & ls, lst const & lr) const;
181     ex subs(ex const & e) const;
182     exvector get_indices(void) const;
183     ex simplify_ncmul(exvector const & v) const;
184     ex operator[](ex const & index) const;
185     ex operator[](int const i) const;
186     ex op(int const i) const;
187     ex & let_op(int const i);
188     int compare(ex const & other) const
189 #ifdef INLINE_EX_CONSTRUCTORS
190         {
191             ASSERT(bp!=0);
192             ASSERT(other.bp!=0);
193             if (bp==other.bp) {
194                 // special case: both expression point to same basic, trivially equal
195                 return 0; 
196             }
197             return bp->compare(*other.bp);
198         }
199 #else
200 ;
201 #endif // def INLINE_EX_CONSTRUCTORS
202     bool is_equal(ex const & other) const
203 #ifdef INLINE_EX_CONSTRUCTORS
204         {
205             ASSERT(bp!=0);
206             ASSERT(other.bp!=0);
207             if (bp==other.bp) {
208                 // special case: both expression point to same basic, trivially equal
209                 return true; 
210             }
211             return bp->is_equal(*other.bp);
212         }
213 #else
214 ;
215 #endif // def INLINE_EX_CONSTRUCTORS
216     bool is_zero(void) const {return compare(exZERO()) == 0;};
217         
218     unsigned return_type(void) const;
219     unsigned return_type_tinfo(void) const;
220     unsigned gethash(void) const;
221
222     ex exadd(ex const & rh) const;
223     ex exmul(ex const & rh) const;
224     ex exncmul(ex const & rh) const;
225 private:
226     void construct_from_basic(basic const & other);
227     void makewriteable();
228
229 // member variables
230
231 public:
232     basic *bp;
233
234 };
235
236 // wrapper functions around member functions
237 inline int nops(ex const & thisex)
238 { return thisex.nops(); }
239
240 inline ex expand(ex const & thisex, unsigned options = 0)
241 { return thisex.expand(options); }
242
243 inline bool has(ex const & thisex, ex const & other)
244 { return thisex.has(other); }
245
246 inline int degree(ex const & thisex, symbol const & s)
247 { return thisex.degree(s); }
248
249 inline int ldegree(ex const & thisex, symbol const & s)
250 { return thisex.ldegree(s); }
251
252 inline ex coeff(ex const & thisex, symbol const & s, int const n=1)
253 { return thisex.coeff(s, n); }
254
255 inline ex numer(ex const & thisex, bool normalize = true)
256 { return thisex.numer(normalize); }
257
258 inline ex denom(ex const & thisex, bool normalize = true)
259 { return thisex.denom(normalize); }
260
261 inline ex normal(ex const & thisex, int level=0)
262 { return thisex.normal(level); }
263
264 inline ex collect(ex const & thisex, symbol const & s)
265 { return thisex.collect(s); }
266
267 inline ex eval(ex const & thisex, int level = 0)
268 { return thisex.eval(level); }
269
270 inline ex evalf(ex const & thisex, int level = 0)
271 { return thisex.evalf(level); }
272
273 inline ex diff(ex const & thisex, symbol const & s, unsigned nth = 1)
274 { return thisex.diff(s, nth); }
275
276 inline ex subs(ex const & thisex, ex const & e)
277 { return thisex.subs(e); }
278
279 inline ex subs(ex const & thisex, lst const & ls, lst const & lr)
280 { return thisex.subs(ls, lr); }
281
282 inline void swap(ex & e1, ex & e2)
283 { e1.swap(e2); }
284
285 #endif // ndef __GINAC_EX_H__