File: analyzer.h

package info (click to toggle)
analitza 4:17.08.3-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 3,824 kB
  • sloc: cpp: 26,899; perl: 63; sh: 16; makefile: 9
file content (236 lines) | stat: -rw-r--r-- 9,793 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*************************************************************************************
 *  Copyright (C) 2007-2010 by Aleix Pol <aleixpol@kde.org>                          *
 *                                                                                   *
 *  This program is free software; you can redistribute it and/or                    *
 *  modify it under the terms of the GNU General Public License                      *
 *  as published by the Free Software Foundation; either version 2                   *
 *  of the License, or (at your option) any later version.                           *
 *                                                                                   *
 *  This program is distributed in the hope that it will be useful,                  *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of                   *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the                    *
 *  GNU General Public License for more details.                                     *
 *                                                                                   *
 *  You should have received a copy of the GNU General Public License                *
 *  along with this program; if not, write to the Free Software                      *
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA   *
 *************************************************************************************/


#ifndef ANALYZER_H
#define ANALYZER_H

#include <QStringList>
#include <QSharedPointer>
#include <QStack>

#include "expression.h"
#include "analitzaexport.h"
#include "expressiontype.h"
#include "builtinmethods.h"
#include <analitza/analitzautils.h>

namespace Analitza
{
class Polynomial;
class Monomial;
class Apply;
class BoundingIterator;
class BuiltinMethods;
class Object;
class Variables;
class Container;
class Operator;
class Ci;

/**
 * \class Analyzer
 * 
 * \ingroup AnalitzaModule
 *
 * \brief The parser: Evaluates and calculates math expressions.
 *
 * Is the base Math class, Analyzer can evaluate simple expressions, expressions 
 * that contains any number of variables and lambda expressions.
 * 
 * If Analyzer is created with a custom Variables module, then calculate() or evaluate() 
 * will be aware of the variables inside the module.
 */

class ANALITZA_EXPORT Analyzer
{
    public:
        /** Constructor. Creates an empty Analyzer module with a Variables module. */
        Analyzer();
        
        /** Constructor. Creates an empty Analyzer module. 
            @param v: Sets a custom variables module. This module will _not_ be deleted along with Analyzer
        */
        explicit Analyzer(Variables* v);
        explicit Analyzer(const QSharedPointer<Variables> &v);
        
        /** Copy constructor. Creates a copy of the @p a Analyzer instance. Inherits its Variable structure. */
        Analyzer(const Analyzer& a);
        
        /** Destructor. */
        ~Analyzer();

        /** sets the @p v Variables tuple we are going to use */
        void setVariables(const QSharedPointer<Variables> &v);
        
        /** Sets an expression to calculate. */
        void setExpression(const Expression &e);
        
        /** Returns the expression in display. */
        const Expression& expression() const { return m_exp; }
        
        /** Calculates the expression and returns a value alone. */
        Expression calculate();
        
        /**
         * Calculates the expression and returns a value alone.
         * The parameters need to be set by passing a stack instance
         */
        Expression calculateLambda();
        
        /** Evaluates an expression, like calculate() but returns a tree. */
        Expression evaluate();
        
        /** Evaluates the derivative of an expression expression, like expression() but sorrounded with a diff(). */
        Expression derivative(const QString& var);
        
        /** Evaluates the derivative of an expression expression. */
        double derivative(const QVector<Object*>& values );
        
        /** Returns whether there has been a problem in the last calculation. */
        bool isCorrect() const { return m_err.isEmpty() && m_exp.isCorrect(); }
        
        /** Empties the error list. */
        void flushErrors() { m_err.clear(); }
        
        /** simplifies the expression. */
        void simplify(); //FIXME: Should return an Expression
        
        /** @returns Return an error list. */
        QStringList errors() const { return m_exp.error() + m_err; }
        
        /** @returns Returns a way to query variables. */
        QSharedPointer<Variables> variables() const { return m_vars; }
        
        /**
            Adds a variable entry. It is the proper way to do it because tracks some possible errors.
            May change the error in case we're trying to represent something wrong.
            @returns Returns if it was actually inserted.
        */
        bool insertVariable(const QString& name, const Expression& value);
        
        /**
            Adds a variable entry. It is the proper way to do it because tracks some possible errors.
            May change the error in case we're trying to represent something wrong.
            @returns Returns if it was actually inserted.
        */
        bool insertVariable(const QString& name, const Object* value);
        
        /**
            Adds a variable entry named @p name with @p value value.
            @returns Returns the added object
        */
        Cn* insertValueVariable(const QString& name, double value);
        
        /** Returns whether the current expression has all data it needs to be calculated.*/
        bool hasDependencies() const { return m_hasdeps; }
        
        /** This method is useful if you want to work programatically on functions with undefined variables.
            @returns the same expression set but with explicit dependencies.
            
            e.g. x+2 would return x->x+2
        */
        Expression dependenciesToLambda() const;
        
        /** This method lets you retrieve the current type in use.
         @returns the type of the current expression.
         */
        ExpressionType type() const { return m_currentType; }
        
        void setStack(const QVector<Object*>& stack) { m_runStack = stack; }
        
        QVector<Object*> runStack() const { return m_runStack; }
        
        BuiltinMethods* builtinMethods();
        
        /** Makes it possible to easily enter a bunch of code to execute it */
        void importScript(QTextStream* stream);
        
        /** @returns the type for any variable that depends on the last executed procedure */
        QMap<QString, ExpressionType> variableTypes() const { return m_variablesTypes; }
    private:
        typedef Object* (Analyzer::*funcContainer)(const Container*);
        static funcContainer operateContainer[];
        
        Expression m_exp;
        QSharedPointer<Variables> m_vars;
        QStringList m_err;
        QVector<Object*> m_runStack;
        int m_runStackTop;
        BuiltinMethods m_builtin;
        
        bool m_hasdeps;
        ExpressionType m_currentType;
        QMap<QString, ExpressionType> m_variablesTypes;
        
        void registerBuiltinMethods(); //util to be called in each ctr
        
        Object* calc(const Object* e);
        Object* operate(const Container*);
        Object* operate(const Apply*);
        Object* eval(const Object* e, bool vars, const QSet<QString>& unscoped);
        
        Object* sum(const Apply& c);
        Object* product(const Apply& c);
        Object* exists(const Apply& c);
        Object* forall(const Apply& c);
        Object* func(const Apply& c);
        Object* calcDiff(const Apply* c);
        Object* calcMap(const Apply* c);
        Object* calcFilter(const Apply* c);
        
        Object* calcPiecewise(const Container* c);
        Object* calcDeclare(const Container* c);
        Object* calcMath(const Container* c);
        Object* calcLambda(const Container* c);
        Object* calcCallFunction(Analitza::Container* function, const QVector<Analitza::Object* >& args, const Analitza::Object* op);
        
        Object* simp(Object* root);
        Object* simpPolynomials(Apply* c);
        Object* simpSum(Apply* c);
        Object* simpApply(Apply* c);
        Object* simpPiecewise(Container* c);
        
        QList<Object*> findRoots(const QString& dep, const Analitza::Object* o);
        QList<Object*> findRootsApply(const QString& dep, const Analitza::Apply* a);
        
        Object* derivative(const QString &var, const Object*);
        Object* boundedOperation(const Apply & n, const Operator & t, Object* initial);
        
        BoundingIterator* initializeBVars(const Apply* n, int base);
        BoundingIterator* initBVarsContainer(const Apply* n, int base, Object* domain);
        BoundingIterator* initBVarsRange(const Apply* n, int base, Object* dlimit, Object* ulimit);
        
        template <class T, class Tit, class Tcontained = Object>
        void iterateAndSimp(T* v);
        
        Object* variableValue(Ci* var);
        Object* testResult(const Analitza::Object* o, const QString& var, const Analitza::Object* val);
        
        template <class T, class Tit, class Tcontained = Object>
        void alphaConversion(T* o, int min);
        void alphaConversion(Apply* a, int min);
        void alphaConversion(Container* a, int min);
        Object* applyAlpha(Analitza::Object* o, int min);
        
        template<class T, class Tit, class Tcontained = Object>
        Object* calcElements(const Analitza::Object* root, T* nv);
};

}
#endif