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 #include <stdio.h>
23 #include <list>
24 #include <map>
25 
26 #include "aterm.hh"
27 #include "exception.hh"
28 #include "mterm.hh"
29 #include "normalize.hh"
30 #include "ppsig.hh"
31 #include "signals.hh"
32 #include "sigorderrules.hh"
33 #include "sigprint.hh"
34 #include "simplify.hh"
35 #include "tlib.hh"
36 
37 #if 0
38 static void countAddTerm(map<Tree,Tree>& M, Tree t, bool invflag);
39 static void incTermCount(map<Tree,int>& M, Tree t, bool invflag);
40 static Tree buildPowTerm(Tree f, int q);
41 static Tree simplifyingReorganizingMul(Tree t1, Tree t2);
42 static Tree reorganizingMul(Tree k, Tree t);
43 static void factorizeAddTerm(map<Tree,Tree>& M);
44 #endif
45 
46 #undef TRACE
47 
48 /**
49  * Compute the Add-Normal form of a term t.
50  * \param t the term to be normalized
51  * \return the normalized term
52  */
normalizeAddTerm(Tree t)53 Tree normalizeAddTerm(Tree t)
54 {
55 #ifdef TRACE
56     cerr << "START normalizeAddTerm : " << ppsig(t) << endl;
57 #endif
58 
59     aterm A(t);
60 #ifdef TRACE
61     cerr << "ATERM of " << A << endl;
62 #endif
63     mterm D = A.greatestDivisor();
64     while (D.isNotZero() && D.complexity() > 0) {
65 #ifdef TRACE
66         cerr << "*** GREAT DIV : " << D << endl;
67 #endif
68         A = A.factorize(D);
69         D = A.greatestDivisor();
70     }
71     Tree r = A.normalizedTree();
72 #ifdef TRACE
73     cerr << "ATERM of " << A << " --> " << ppsig(r) << endl;
74 #endif
75     return r;
76 }
77 
78 /**
79  * Compute the normal form of a 1-sample delay term s'.
80  * The normalisation rules are :
81  *     	0' -> 0 /// INACTIVATE dec07 bug recursion
82  *     	(k*s)' -> k*s'
83  *		(s/k)' -> s'/k
84  * \param s the term to be delayed by 1 sample
85  * \return the normalized term
86  */
normalizeDelay1Term(Tree s)87 Tree normalizeDelay1Term(Tree s)
88 {
89     return normalizeDelayTerm(s, tree(1));
90 }
91 
92 /**
93  * Compute the normal form of a fixed delay term (s@d).
94  * The normalisation rules are :
95  *		s@0 -> s
96  *     	0@d -> 0
97  *     	(k*s)@d -> k*(s@d)
98  *		(s/k)@d -> (s@d)/k
99  * 		(s@n)@m -> s@(n+m) and n is constant
100  * Note that the same rules can't be applied to
101  * + and - because the value of the first d samples
102  * would be wrong.
103  * \param s the term to be delayed
104  * \param d the value of the delay
105  * \return the normalized term
106  */
107 
normalizeDelayTerm(Tree s,Tree d)108 Tree normalizeDelayTerm(Tree s, Tree d)
109 {
110     Tree x, y, r;
111     int  i;
112 
113     if (isZero(d)) {
114         if (isProj(s, &i, r)) {
115             return sigDelay(s, d);
116         } else {
117             return s;
118         }
119 
120     } else if (isZero(s)) {
121         return s;
122 
123     } else if (isSigMul(s, x, y)) {
124         if (getSigOrder(x) < 2) {
125             return /*simplify*/ (sigMul(x, normalizeDelayTerm(y, d)));
126         } else if (getSigOrder(y) < 2) {
127             return /*simplify*/ (sigMul(y, normalizeDelayTerm(x, d)));
128         } else {
129             return sigDelay(s, d);
130         }
131 
132     } else if (isSigDiv(s, x, y)) {
133         if (getSigOrder(y) < 2) {
134             return /*simplify*/ (sigDiv(normalizeDelayTerm(x, d), y));
135         } else {
136             return sigDelay(s, d);
137         }
138 
139     } else if (isSigDelay(s, x, y)) {
140         if (getSigOrder(y) < 2) {
141             // (x@n)@m = x@(n+m) when n is constant
142             return normalizeDelayTerm(x, simplify(sigAdd(d, y)));
143         } else {
144             return sigDelay(s, d);
145         }
146 
147     } else {
148         return sigDelay(s, d);
149     }
150 }
151