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