File indexing completed on 2024-04-28 03:40:40
0001 /************************************************************************************* 0002 * Copyright (C) 2007-2010 by Aleix Pol <aleixpol@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or * 0005 * modify it under the terms of the GNU General Public License * 0006 * as published by the Free Software Foundation; either version 2 * 0007 * of the License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the Free Software * 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0017 *************************************************************************************/ 0018 0019 0020 #ifndef ANALYZER_H 0021 #define ANALYZER_H 0022 0023 #include <QStringList> 0024 #include <QSharedPointer> 0025 #include <QStack> 0026 0027 #include "expression.h" 0028 #include "analitzaexport.h" 0029 #include "expressiontype.h" 0030 #include "builtinmethods.h" 0031 #include <analitza/analitzautils.h> 0032 0033 namespace Analitza 0034 { 0035 class Polynomial; 0036 class Apply; 0037 class BoundingIterator; 0038 class BuiltinMethods; 0039 class Object; 0040 class Variables; 0041 class Container; 0042 class Operator; 0043 class Ci; 0044 0045 /** 0046 * \class Analyzer 0047 * 0048 * \ingroup AnalitzaModule 0049 * 0050 * \brief The parser: Evaluates and calculates math expressions. 0051 * 0052 * Is the base Math class, Analyzer can evaluate simple expressions, expressions 0053 * that contains any number of variables and lambda expressions. 0054 * 0055 * If Analyzer is created with a custom Variables module, then calculate() or evaluate() 0056 * will be aware of the variables inside the module. 0057 */ 0058 0059 class ANALITZA_EXPORT Analyzer 0060 { 0061 public: 0062 /** Constructor. Creates an empty Analyzer module with a Variables module. */ 0063 Analyzer(); 0064 0065 /** Constructor. Creates an empty Analyzer module. 0066 @param v: Sets a custom variables module. This module will _not_ be deleted along with Analyzer 0067 */ 0068 explicit Analyzer(Variables* v); 0069 explicit Analyzer(const QSharedPointer<Variables> &v); 0070 0071 /** Copy constructor. Creates a copy of the @p a Analyzer instance. Inherits its Variable structure. */ 0072 Analyzer(const Analyzer& a); 0073 0074 /** Destructor. */ 0075 ~Analyzer(); 0076 0077 /** sets the @p v Variables tuple we are going to use */ 0078 void setVariables(const QSharedPointer<Variables> &v); 0079 0080 /** Sets an expression to calculate. */ 0081 void setExpression(const Expression &e); 0082 0083 /** Returns the expression in display. */ 0084 const Expression& expression() const { return m_exp; } 0085 0086 /** Calculates the expression and returns a value alone. */ 0087 Expression calculate(); 0088 0089 /** 0090 * Calculates the expression and returns a value alone. 0091 * The parameters need to be set by passing a stack instance 0092 */ 0093 Expression calculateLambda(); 0094 0095 /** Evaluates an expression, like calculate() but returns a tree. */ 0096 Expression evaluate(); 0097 0098 /** Evaluates the derivative of an expression expression, like expression() but sorrounded with a diff(). */ 0099 Expression derivative(const QString& var); 0100 0101 /** Evaluates the derivative of an expression expression. */ 0102 double derivative(const QVector<Object*>& values ); 0103 0104 /** Returns whether there has been a problem in the last calculation. */ 0105 bool isCorrect() const { return m_err.isEmpty() && m_exp.isCorrect(); } 0106 0107 /** Empties the error list. */ 0108 void flushErrors() { m_err.clear(); } 0109 0110 /** simplifies the expression. */ 0111 void simplify(); //FIXME: Should return an Expression 0112 0113 /** @returns Return an error list. */ 0114 QStringList errors() const { return m_exp.error() + m_err; } 0115 0116 /** @returns Returns a way to query variables. */ 0117 QSharedPointer<Variables> variables() const { return m_vars; } 0118 0119 /** 0120 Adds a variable entry. It is the proper way to do it because tracks some possible errors. 0121 May change the error in case we're trying to represent something wrong. 0122 @returns Returns if it was actually inserted. 0123 */ 0124 bool insertVariable(const QString& name, const Expression& value); 0125 0126 /** 0127 Adds a variable entry. It is the proper way to do it because tracks some possible errors. 0128 May change the error in case we're trying to represent something wrong. 0129 @returns Returns if it was actually inserted. 0130 */ 0131 bool insertVariable(const QString& name, const Object* value); 0132 0133 /** 0134 Adds a variable entry named @p name with @p value value. 0135 @returns Returns the added object 0136 */ 0137 Cn* insertValueVariable(const QString& name, double value); 0138 0139 /** Returns whether the current expression has all data it needs to be calculated.*/ 0140 bool hasDependencies() const { return m_hasdeps; } 0141 0142 /** This method is useful if you want to work programatically on functions with undefined variables. 0143 @returns the same expression set but with explicit dependencies. 0144 0145 e.g. x+2 would return x->x+2 0146 */ 0147 Expression dependenciesToLambda() const; 0148 0149 /** This method lets you retrieve the current type in use. 0150 @returns the type of the current expression. 0151 */ 0152 ExpressionType type() const { return m_currentType; } 0153 0154 void setStack(const QVector<Object*>& stack) { m_runStack = stack; } 0155 0156 QVector<Object*> runStack() const { return m_runStack; } 0157 0158 BuiltinMethods* builtinMethods(); 0159 0160 /** Makes it possible to easily enter a bunch of code to execute it */ 0161 void importScript(QTextStream* stream); 0162 0163 /** @returns the type for any variable that depends on the last executed procedure */ 0164 QMap<QString, ExpressionType> variableTypes() const { return m_variablesTypes; } 0165 private: 0166 typedef Object* (Analyzer::*funcContainer)(const Container*); 0167 static funcContainer operateContainer[]; 0168 0169 Expression m_exp; 0170 QSharedPointer<Variables> m_vars; 0171 QStringList m_err; 0172 QVector<Object*> m_runStack; 0173 int m_runStackTop; 0174 BuiltinMethods m_builtin; 0175 0176 bool m_hasdeps; 0177 ExpressionType m_currentType; 0178 QMap<QString, ExpressionType> m_variablesTypes; 0179 0180 void registerBuiltinMethods(); //util to be called in each ctr 0181 0182 Object* calc(const Object* e); 0183 Object* operate(const Container*); 0184 Object* operate(const Apply*); 0185 Object* eval(const Object* e, bool vars, const QSet<QString>& unscoped); 0186 0187 Object* sum(const Apply& c); 0188 Object* product(const Apply& c); 0189 Object* exists(const Apply& c); 0190 Object* forall(const Apply& c); 0191 Object* func(const Apply& c); 0192 Object* calcDiff(const Apply* c); 0193 Object* calcMap(const Apply* c); 0194 Object* calcFilter(const Apply* c); 0195 0196 Object* calcPiecewise(const Container* c); 0197 Object* calcDeclare(const Container* c); 0198 Object* calcMath(const Container* c); 0199 Object* calcLambda(const Container* c); 0200 Object* calcCallFunction(Analitza::Container* function, const QVector<Analitza::Object* >& args, const Analitza::Object* op); 0201 0202 Object* simp(Object* root); 0203 Object* simpPolynomials(Apply* c); 0204 Object* simpSum(Apply* c); 0205 Object* simpApply(Apply* c); 0206 Object* simpPiecewise(Container* c); 0207 0208 QList<Object*> findRoots(const QString& dep, const Analitza::Object* o); 0209 QList<Object*> findRootsApply(const QString& dep, const Analitza::Apply* a); 0210 0211 Object* derivative(const QString &var, const Object*); 0212 Object* boundedOperation(const Apply & n, const Operator & t, Object* initial); 0213 0214 BoundingIterator* initializeBVars(const Apply* n, int base); 0215 BoundingIterator* initBVarsContainer(const Apply* n, int base, Object* domain); 0216 BoundingIterator* initBVarsRange(const Apply* n, int base, Object* dlimit, Object* ulimit); 0217 0218 template <class T, class Tcontained = Object> 0219 void iterateAndSimp(T* v); 0220 0221 Object* variableValue(Ci* var); 0222 Object* testResult(const Analitza::Object* o, const QString& var, const Analitza::Object* val); 0223 0224 template <class T, class Tcontained = Object> 0225 void alphaConversion(T* o, int min); 0226 void alphaConversion(Apply* a, int min); 0227 void alphaConversion(Container* a, int min); 0228 Object* applyAlpha(Analitza::Object* o, int min); 0229 0230 template<class T, class Tcontained = Object> 0231 Object* calcElements(const Analitza::Object* root, T* nv); 0232 0233 template<class T, class Tcontained = Object> 0234 Object* evalElements(const Analitza::Object* root, T* nv, bool resolve, const QSet<QString>& unscoped); 0235 }; 0236 0237 } 0238 #endif