- ASSERT macro renamed to GINAC_ASSERT
[ginac.git] / ginac / expair.h
1 /** @file expair.h
2  *
3  *  Definition of expression pairs (building blocks of expairseq). */
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_EXPAIR_H__
24 #define __GINAC_EXPAIR_H__
25
26 #include <ginac/ex.h>
27 #include <ginac/numeric.h>
28
29 namespace GiNaC {
30
31 /** A pair of expressions.
32  *  This similar to, but slightly extended STL's pair<> but we need to account
33  *  for methods like .compare() */
34 class expair
35 {
36 public:
37     expair() {}
38     ~expair() {}
39     expair(expair const & other) : rest(other.rest), coeff(other.coeff)
40     {
41         GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
42     }
43     expair const & operator=(expair const & other)
44     {
45         if (this != &other) {
46             rest=other.rest;
47             coeff=other.coeff;
48         }
49         return *this;
50     }
51     expair(ex const & r, ex const & c) : rest(r), coeff(c)
52     {
53         GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
54     }
55     
56     bool is_numeric_with_coeff_1(void) const
57     {
58         GINAC_ASSERT(is_ex_exactly_of_type(coeff,numeric));
59         return is_ex_exactly_of_type(rest,numeric) &&
60                (ex_to_numeric(coeff).compare(numONE())==0);
61     }
62
63     bool is_equal(expair const & other) const
64     {
65         return (rest.is_equal(other.rest) && coeff.is_equal(other.coeff));
66     }
67     bool is_less(expair const & other) const 
68     {
69         return (rest.compare(other.rest)<0) ||
70                (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
71     }
72     int compare(expair const & other) const
73     {
74         int cmpval=rest.compare(other.rest);
75         if (cmpval!=0) return cmpval;
76         cmpval=coeff.compare(other.coeff);
77         return cmpval;
78     }
79
80     bool is_less_old2(expair const & other) const 
81     {
82         /*
83         bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
84         bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
85         if (this_numeric_with_coeff_1) {
86             if (other_numeric_with_coeff_1) {
87                 // both have coeff 1: compare rests
88                 return rest.compare(other.rest)<0;
89             }
90             // only this has coeff 1: >
91             return false;
92         } else if (other_numeric_with_coeff_1) {
93             // only other has coeff 1: <
94             return true;
95         }
96         return (rest.compare(other.rest)<0) ||
97                (!(other.rest.compare(rest)<0) &&
98                  (coeff.compare(other.coeff)<0));
99         */
100         if (is_ex_exactly_of_type(rest,numeric) &&
101             is_ex_exactly_of_type(other.rest,numeric)) {
102             if (ex_to_numeric(coeff).compare(numONE())==0) {
103                 if (ex_to_numeric(other.coeff).compare(numONE())==0) {
104                     // both have coeff 1: compare rests
105                     return rest.compare(other.rest)<0;
106                 }
107                 // only this has coeff 1: >
108                 return false;
109             } else if (ex_to_numeric(other.coeff).compare(numONE())==0) {
110                 // only other has coeff 1: <
111                 return true;
112             }
113             // neither has coeff 1: usual compare        
114         }
115         return (rest.compare(other.rest)<0) ||
116                (!(other.rest.compare(rest)<0) &&
117                  (coeff.compare(other.coeff)<0));
118     }
119     int compare_old2(expair const & other) const
120     {
121         if (is_ex_exactly_of_type(rest,numeric) &&
122             is_ex_exactly_of_type(other.rest,numeric)) {
123             if (ex_to_numeric(coeff).compare(numONE())==0) {
124                 if (ex_to_numeric(other.coeff).compare(numONE())==0) {
125                     // both have coeff 1: compare rests
126                     return rest.compare(other.rest);
127                 }
128                 // only this has coeff 1: >
129                 return 1;
130             } else if (ex_to_numeric(other.coeff).compare(numONE())==0) {
131                 // only other has coeff 1: <
132                 return -1;
133             }
134             // neither has coeff 1: usual compare        
135         }
136         /*
137         bool this_numeric_with_coeff_1=is_numeric_with_coeff_1();
138         bool other_numeric_with_coeff_1=other.is_numeric_with_coeff_1();
139         if (this_numeric_with_coeff_1) {
140             if (other_numeric_with_coeff_1) {
141                 // both have coeff 1: compare rests
142                 return rest.compare(other.rest);
143             }
144             // only this has coeff 1: >
145             return 1;
146         } else if (other_numeric_with_coeff_1) {
147             // only other has coeff 1: <
148             return -1;
149             // neither has coeff 1: usual compare        
150         }
151         */
152         int cmpval=rest.compare(other.rest);
153         if (cmpval!=0) return cmpval;
154         return coeff.compare(other.coeff);
155     }
156     bool is_less_old(expair const & other) const 
157     {
158         return (rest.compare(other.rest)<0) ||
159                (!(other.rest.compare(rest)<0) && (coeff.compare(other.coeff)<0));
160     }
161     int compare_old(expair const & other) const
162     {
163         int cmpval=rest.compare(other.rest);
164         if (cmpval!=0) return cmpval;
165         cmpval=coeff.compare(other.coeff);
166         return cmpval;
167     }
168
169     void printraw(ostream & os) const
170     {
171         os << "expair(";
172         rest.printraw(os);
173         os << ",";
174         coeff.printraw(os);
175         os << ")";
176     }
177
178     ex rest;
179     ex coeff;
180 };
181
182 class expair_is_less
183 {
184 public:
185     bool operator()(expair const & lh, expair const & rh) const
186     {
187         return lh.is_less(rh);
188     }
189 };
190
191 class expair_is_less_old
192 {
193 public:
194     bool operator()(expair const & lh, expair const & rh) const
195     {
196         return lh.is_less_old(rh);
197     }
198 };
199
200 } // namespace GiNaC
201
202 #endif // ndef __GINAC_EXPAIR_H__