1 /************************************************************************
2  ************************************************************************
3     FAUST compiler
4     Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5     ---------------------------------------------------------------------
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  ************************************************************************
20  ************************************************************************/
21 
22 #ifndef __MTERM__
23 #define __MTERM__
24 
25 #include <stdio.h>
26 #include <list>
27 #include <map>
28 
29 #include "exception.hh"
30 #include "garbageable.hh"
31 #include "normalize.hh"
32 #include "signals.hh"
33 #include "sigorderrules.hh"
34 #include "sigprint.hh"
35 #include "simplify.hh"
36 #include "tlib.hh"
37 
38 using namespace std;
39 
40 /**
41  * Implements a multiplicative term, a term of type
42  * k*x^n*y^m*... and its arithmetic.
43  */
44 
45 struct CompareTree {
operator ()CompareTree46     bool operator()(Tree t1, Tree t2) const { return t1->serial() < t2->serial(); }
47 };
48 
49 class mterm : public virtual Garbageable {
50     Tree                        fCoef;     ///< constant part of the term (usually 1 or -1)
51     map<Tree, int, CompareTree> fFactors;  ///< non constant terms and their power
52 
53    public:
54     mterm();                ///< create a 0 mterm
55     mterm(int k);           ///< create a simple integer mterm
56     mterm(double k);        ///< create a simple float mterm
57     mterm(Tree t);          ///< create a mterm from a multiplicative exp
58     mterm(const mterm& m);  ///< create a copy of a mterm
59 
60     void cleanup();           ///< remove used factors
61     bool isNotZero() const;   ///< true if mterm doesn't represent number 0
62     bool isNegative() const;  ///< true if mterm has a negative coefficient
63 
64     const mterm& operator=(const mterm& m);  ///< replace the content with a copy of m
65 
66     const mterm& operator*=(Tree m);  ///< multiply in place by a multiplicative exp
67     const mterm& operator/=(Tree m);  ///< divide in place by a multiplicative exp
68 
69     const mterm& operator+=(const mterm& m);  ///< add in place an mterm of same signature
70     const mterm& operator-=(const mterm& m);  ///< add in place an mterm of same signature
71 
72     const mterm& operator*=(const mterm& m);  ///< multiply in place by a mterm
73     const mterm& operator/=(const mterm& m);  ///< divide in place by a mterm
74 
75     mterm    operator*(const mterm& m) const;  ///< mterms multiplication
76     mterm    operator/(const mterm& m) const;  ///< mterms division
77     ostream& print(ostream& dst) const;        ///< print a mterm k*x1**n1*x2**n2...
78 
79     int  complexity() const;  ///< return an evaluation of the complexity
80     Tree normalizedTree(bool sign = false,
81                         bool neg  = false) const;  ///< return the normalized tree of the mterm
82     Tree signatureTree() const;                    ///< return a signature (a normalized tree)
83 
84     bool         hasDivisor(const mterm& n) const;       ///< return true if this can be divided by n
85     friend mterm gcd(const mterm& m1, const mterm& m2);  /// greatest common divisor of two mterms
86 };
87 
operator <<(ostream & s,const mterm & m)88 inline ostream& operator<<(ostream& s, const mterm& m)
89 {
90     return m.print(s);
91 }
92 
93 #endif
94