File indexing completed on 2024-04-28 03:40:40

0001 /*************************************************************************************
0002  *  Copyright (C) 2007 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 #include "container.h"
0019 
0020 #include "expression.h"
0021 #include "abstractexpressionvisitor.h"
0022 #include "vector.h"
0023 #include "value.h"
0024 #include "list.h"
0025 
0026 #include <QDebug>
0027 
0028 #include "variable.h"
0029 #include "analitzautils.h"
0030 
0031 using namespace Analitza;
0032 
0033 char Container::m_typeStr[][20] = {
0034         "none",
0035         "math",
0036         "declare",
0037         "lambda",
0038         "bvar",
0039         "uplimit",
0040         "downlimit",
0041         "piece",
0042         "piecewise",
0043         "otherwise",
0044         "domainofapplication"
0045 };
0046 
0047 QMap<QString, Container::ContainerType> createNameToType()
0048 {
0049     QMap<QString, Container::ContainerType> ret;
0050     ret[QStringLiteral("declare")]=Container::declare;
0051     ret[QStringLiteral("math")]=Container::math;
0052     ret[QStringLiteral("lambda")]=Container::lambda;
0053     ret[QStringLiteral("bvar")]=Container::bvar;
0054     ret[QStringLiteral("uplimit")]=Container::uplimit;
0055     ret[QStringLiteral("downlimit")]=Container::downlimit;
0056     ret[QStringLiteral("piecewise")]=Container::piecewise;
0057     ret[QStringLiteral("piece")]=Container::piece;
0058     ret[QStringLiteral("otherwise")]=Container::otherwise;
0059     ret[QStringLiteral("domainofapplication")]=Container::domainofapplication;
0060     
0061     return ret;
0062 }
0063 
0064 QMap<QString, Container::ContainerType> Container::m_nameToType=createNameToType();
0065 
0066 Container::Container(const Container& c) : Object(Object::container), m_cont_type(c.m_cont_type)
0067 {
0068     Q_ASSERT(c.type()==Object::container);
0069     
0070     foreach(const Object* o, c.m_params)
0071         appendBranch(o->copy());
0072 }
0073 
0074 Container* Container::copy() const
0075 {
0076     return new Container(*this);
0077 }
0078 
0079 QVariant Container::accept(AbstractExpressionVisitor* e) const
0080 {
0081     return e->visit(this);
0082 }
0083 
0084 bool Container::isZero() const
0085 {
0086     bool a=true;
0087     foreach(const Object* o, m_params) {
0088         a = a && o->isZero();
0089     }
0090     return a;
0091 }
0092 
0093 Container::ContainerType Container::toContainerType(const QString& tag)
0094 {
0095     return m_nameToType[tag];
0096 }
0097 
0098 QList<Ci*> Container::bvarCi() const
0099 {
0100     QList<Ci*> ret;
0101     QList<Object*>::const_iterator it, itEnd=m_params.constEnd();
0102     
0103     for(it=m_params.constBegin(); it!=itEnd; ++it) {
0104         if((*it)->isContainer()) {
0105             Container* c = (Container*) (*it);
0106             if(c->containerType() == Container::bvar) {
0107                 Q_ASSERT(!c->isEmpty() && c->m_params[0]->type()==Object::variable);
0108                 ret.append((Ci*) c->m_params[0]);
0109             }
0110         }
0111     }
0112     
0113     return ret;
0114 }
0115 
0116 int Container::bvarCount() const
0117 {
0118     int r=0;
0119     QList<Object*>::const_iterator it, itEnd=m_params.constEnd();
0120     for(it=m_params.constBegin(); it!=itEnd; ++it) {
0121         Object* o = *it;
0122         if(o->isContainer() && static_cast<Container*>(o)->containerType() == Container::bvar)
0123             r++;
0124     }
0125     
0126     return r;
0127 }
0128 
0129 QStringList Container::bvarStrings() const
0130 {
0131     QStringList bvars;
0132     QList< Ci* > vars=bvarCi();
0133     foreach(Ci* var, vars) {
0134         bvars.append(var->name());
0135     }
0136     
0137     return bvars;
0138 }
0139 
0140 bool Container::operator==(const Container& c) const
0141 {
0142     bool eq=c.m_params.count()==m_params.count();
0143     
0144     for(int i=0; eq && i<m_params.count(); ++i) {
0145         Object *o=m_params[i], *o1=c.m_params[i];
0146         eq = eq && AnalitzaUtils::equalTree(o, o1);
0147     }
0148     return eq;
0149 }
0150 
0151 bool Container::isNumber() const
0152 {
0153     return m_cont_type==math || m_cont_type==lambda || m_cont_type==declare ||
0154         m_cont_type==piecewise || m_cont_type==piece || m_cont_type==otherwise;
0155 }
0156 
0157 QString Container::tagName() const
0158 {
0159     return QString(m_typeStr[m_cont_type]);
0160 }
0161 
0162 bool Container::matches(const Object* exp, QMap<QString, const Object*>* found) const
0163 {
0164     if(Object::container!=exp->type())
0165         return false;
0166     const Container* c=(const Container*) exp;
0167     if(m_params.count()!=c->m_params.count())
0168         return false;
0169     
0170     bool matching=true;
0171     Container::const_iterator it, it2, itEnd=m_params.constEnd();
0172     for(it=m_params.constBegin(), it2=c->m_params.constBegin(); matching && it!=itEnd; ++it, ++it2)
0173     {
0174         matching &= (*it)->matches(*it2, found);
0175     }
0176     return matching;
0177 }
0178 
0179 const Container* Container::extractType(Container::ContainerType t) const
0180 {
0181     for(Container::const_iterator it=m_params.constBegin(); it!=m_params.constEnd(); ++it) {
0182         const Container *c = (const Container*) (*it);
0183         if(c->isContainer() && c->containerType()==t)
0184             return c;
0185     }
0186     return nullptr;
0187 }
0188 
0189 void Container::appendBranch(Object* o)
0190 {
0191     m_params.append(o);
0192 }