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 #include "apply.h" 0020 #include "abstractexpressionvisitor.h" 0021 #include <QStringList> 0022 #include "variable.h" 0023 #include "analitzautils.h" 0024 #include "container.h" 0025 0026 using namespace Analitza; 0027 0028 Apply::Apply() 0029 : Object(apply), m_ulimit(nullptr), m_dlimit(nullptr), m_domain(nullptr), m_op(Operator::function) 0030 {} 0031 0032 Apply::~Apply() 0033 { 0034 delete m_dlimit; 0035 delete m_ulimit; 0036 delete m_domain; 0037 qDeleteAll(m_bvars); 0038 qDeleteAll(m_params); 0039 } 0040 0041 bool Apply::addBranch(Object* o) 0042 { 0043 if(o->type()==Object::oper) { 0044 m_op = *static_cast<Operator*>(o); 0045 delete o; 0046 } else if(o->isContainer()) { 0047 Container* c=static_cast<Container*>(o); 0048 switch(c->containerType()) { 0049 case Container::uplimit: 0050 Q_ASSERT(!m_ulimit); 0051 m_ulimit = c->m_params[0]; 0052 c->m_params[0]=nullptr; 0053 delete c; 0054 break; 0055 case Container::downlimit: 0056 Q_ASSERT(!m_dlimit); 0057 m_dlimit = c->m_params[0]; 0058 c->m_params[0]=nullptr; 0059 delete c; 0060 break; 0061 case Container::domainofapplication: 0062 Q_ASSERT(!m_domain); 0063 m_domain = c->m_params[0]; 0064 c->m_params[0]=nullptr; 0065 delete c; 0066 break; 0067 case Container::bvar: 0068 Q_ASSERT(c->m_params[0]->type()==variable); 0069 m_bvars += static_cast<Ci*>(c->m_params[0]); 0070 c->m_params[0]=nullptr; 0071 delete c; 0072 break; 0073 default: 0074 return false; 0075 } 0076 } else 0077 return false; 0078 0079 return true; 0080 } 0081 0082 void Apply::appendBranch(Object *o) 0083 { 0084 if(!addBranch(o)) 0085 m_params.append(o); 0086 } 0087 0088 void Apply::prependBranch(Object* o) 0089 { 0090 if(!addBranch(o)) 0091 m_params.prepend(o); 0092 } 0093 0094 QVariant Apply::accept(AbstractExpressionVisitor* exp) const 0095 { 0096 return exp->visit(this); 0097 } 0098 0099 QStringList Apply::bvarStrings() const 0100 { 0101 QStringList ret; 0102 foreach(const Ci* bvar, m_bvars) { 0103 ret.append(bvar->name()); 0104 } 0105 return ret; 0106 } 0107 0108 bool Apply::operator==(const Apply& a) const 0109 { 0110 bool eq=a.m_params.count()==m_params.count() && a.firstOperator()==firstOperator(); 0111 eq &= bool(a.ulimit())==bool(m_ulimit); 0112 eq &= bool(a.dlimit())==bool(m_dlimit); 0113 eq &= bool(a.domain())==bool(m_domain); 0114 0115 if(m_ulimit) eq &= AnalitzaUtils::equalTree(m_ulimit, a.m_ulimit); 0116 if(m_dlimit) eq &= AnalitzaUtils::equalTree(m_dlimit, a.m_dlimit); 0117 if(m_domain) eq &= AnalitzaUtils::equalTree(m_domain, a.m_domain); 0118 0119 for(int i=0; eq && i<m_params.count(); ++i) { 0120 Object *o=m_params[i], *o1=a.m_params[i]; 0121 eq = eq && AnalitzaUtils::equalTree(o, o1); 0122 } 0123 0124 return eq; 0125 } 0126 0127 Apply* Apply::copy() const 0128 { 0129 Apply* ret=new Apply; 0130 ret->m_dlimit = m_dlimit? m_dlimit->copy() : nullptr; 0131 ret->m_ulimit = m_ulimit? m_ulimit->copy() : nullptr; 0132 ret->m_domain = m_domain? m_domain->copy() : nullptr; 0133 ret->m_op = m_op; 0134 0135 foreach(const Ci* var, m_bvars) 0136 ret->m_bvars += (Ci*) var->copy(); 0137 0138 foreach(const Object* o, m_params) 0139 ret->m_params += o->copy(); 0140 0141 return ret; 0142 } 0143 0144 bool Apply::matches(const Object* exp, QMap<QString, const Object*>* found) const 0145 { 0146 if(Object::apply!=exp->type()) 0147 return false; 0148 const Apply* c=(const Apply*) exp; 0149 if(m_params.count()!=c->m_params.count()) 0150 return false; 0151 0152 QVector<Ci*> vars=m_bvars, cvars = c->bvarCi(); 0153 bool matching=vars.size()==cvars.size(); 0154 matching &= m_op.matches(&c->m_op, found); 0155 0156 for(QVector<Ci*>::const_iterator it=vars.constBegin(), cit=cvars.constBegin(), itEnd=vars.constEnd(); matching && it!=itEnd; ++it) { 0157 matching &= (*it)->matches(*cit, found); 0158 } 0159 0160 // bool matching=true; 0161 Apply::const_iterator it, it2, itEnd=m_params.constEnd(); 0162 for(it=m_params.constBegin(), it2=c->m_params.constBegin(); matching && it!=itEnd; ++it, ++it2) 0163 matching &= (*it)->matches(*it2, found); 0164 0165 matching &= bool(m_ulimit)==bool(c->m_ulimit) && (!m_ulimit || m_ulimit->matches(c->m_ulimit, found)); 0166 matching &= bool(m_dlimit)==bool(c->m_dlimit) && (!m_dlimit || m_dlimit->matches(c->m_dlimit, found)); 0167 matching &= bool(m_domain)==bool(c->m_domain) && (!m_domain || m_domain->matches(c->m_domain, found)); 0168 return matching; 0169 } 0170 0171 bool Analitza::Apply::hasBoundings() const 0172 { 0173 return m_dlimit || m_ulimit || m_domain; 0174 } 0175 0176 void Apply::addBVar(Ci* bvar) 0177 { 0178 m_bvars += bvar; 0179 } 0180 0181 Object* Apply::at(int p) const 0182 { 0183 return m_params.at(p); 0184 }