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

0001 /*************************************************************************************
0002  *  Copyright (C) 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 "expressiontype.h"
0020 #include <QStringList>
0021 #include <QDebug>
0022 
0023 using namespace Analitza;
0024 
0025 QDebug operator<<(QDebug dbg, const ExpressionType &c);
0026 namespace Analitza { void printAssumptions(const QString& prefix, const ExpressionType& current); }
0027 QDebug operator<<(QDebug dbg, const QMap<int, Analitza::ExpressionType> &c);
0028 
0029 bool ExpressionType::assumptionsMerge(QMap<QString, ExpressionType>& data, const QMap<QString, ExpressionType>& newmap)
0030 {
0031     if(data.isEmpty() && newmap.isEmpty())
0032         return true;
0033     
0034 //     static int i=0;
0035 //     qDebug() << "merging!" << i++ << data << newmap;
0036     QMap<int, ExpressionType> stars;
0037     QMap<QString, ExpressionType>::const_iterator it=newmap.constBegin(), itEnd=newmap.constEnd();
0038     for(; it!=itEnd; ++it) {
0039         QMap<QString, ExpressionType>::iterator current = data.find(it.key());
0040         
0041         if(current!=data.end()) {
0042             if(!current->isError()) {
0043                 ExpressionType t=ExpressionType::minimumType(*it, *current);
0044 //                 qDebug() << "miiiiiiin" << it.key() << *it << *current << t << "|||" << it->assumptions() << current->assumptions() << t.assumptions();
0045                 if(t.isError())
0046                     return false;
0047                 
0048                 stars=computeStars(stars, *it, *current);
0049                 *current = t.starsToType(stars);
0050             }
0051         } else
0052             data.insert(it.key(), it.value());
0053     }
0054 //     qDebug() << "merging_" << data;
0055     
0056     for(QMap<QString, ExpressionType>::iterator it=data.begin(); it!=data.end(); ++it) {
0057         *it=it->starsToType(stars);
0058     }
0059     
0060 //     i--;
0061     return true;
0062 }
0063 
0064 void ExpressionType::assumptionsUnion(QMap<QString, ExpressionType>& data, const QMap<QString, ExpressionType>& newmap)
0065 {
0066 //     qDebug() << "-----------" << data << newmap;
0067     QMap<QString, ExpressionType>::const_iterator it=newmap.constBegin(), itEnd=newmap.constEnd();
0068     for(; it!=itEnd; ++it) {
0069         QMap<QString, ExpressionType>::iterator current = data.find(it.key());
0070         
0071         if(current!=data.end()) {
0072             if(current->canReduceTo(*it)) {
0073                 data.insert(it.key(), minimumType(*current, *it));
0074             } else {
0075                 bool correct=false;
0076                 ExpressionType t(Many);
0077                 ExpressionType t1(*it);            correct= t1.addAssumption(it.key(), *it);
0078                 ExpressionType t2(*current);    correct|=t2.addAssumption(it.key(), *current);
0079                 
0080                 Q_ASSERT(correct);
0081                 t.addAlternative(t1);
0082                 t.addAlternative(t2);
0083                 
0084                 data.insert(it.key(), t);
0085             }
0086         } else
0087             data.insert(it.key(), it.value());
0088     }
0089     
0090 //     qDebug() << "leeeeee" << data;
0091 }
0092 
0093 ExpressionType::ExpressionType(const ExpressionType& t)
0094     : m_type(t.m_type), m_contained(t.m_contained)
0095     , m_assumptions(t.m_assumptions), m_size(t.m_size), m_objectName(t.m_objectName)
0096 {}
0097 
0098 ExpressionType::ExpressionType(ExpressionType::Type t, int any)
0099     : m_type(t), m_any(any)
0100 {Q_ASSERT(m_type==Any || m_type==Error || m_type==Value || m_type==Bool || m_type==Char || m_type==Many || m_type==Lambda); }
0101 
0102 ExpressionType::ExpressionType(ExpressionType::Type t, const ExpressionType& contained, int s)
0103     : m_type(t), m_contained(QList<ExpressionType>() << contained), m_size(s)
0104 {
0105     Q_ASSERT(m_type==List || m_type==Vector || m_type==Matrix || m_type==Any); // Any for variadic functions with same contained type
0106     Q_ASSERT(m_type!=Vector || m_size!=0);
0107     Q_ASSERT(m_type!=Matrix || contained.type()==Vector);
0108     m_assumptions=contained.assumptions();
0109 }
0110 
0111 ExpressionType::ExpressionType(const QString& objectName)
0112     : m_type(Object), m_size(-1), m_objectName(objectName)
0113 {}
0114 
0115 ExpressionType::ExpressionType(ExpressionType::Type t, const QList< ExpressionType >& alternatives)
0116     : m_type(Many), m_size(-1)
0117 {
0118     Q_ASSERT(t==Many);
0119     foreach(const ExpressionType& t, alternatives)
0120         addAlternative(t);
0121 }
0122 
0123 QStringList typesToString(const QList<ExpressionType>& types)
0124 {
0125     QStringList ret;
0126     foreach(const ExpressionType& t, types) {
0127         QString str=t.toString();
0128         if(t.type()==ExpressionType::Lambda)
0129             ret += '('+str+')';
0130         else
0131             ret += str;
0132     }
0133     return ret;
0134 }
0135 
0136 QString ExpressionType::toString() const
0137 {
0138     QString ret;
0139     switch(m_type) {
0140         case ExpressionType::Value:ret=QStringLiteral("num");  break;
0141         case ExpressionType::Char: ret=QStringLiteral("char"); break;
0142         case ExpressionType::Bool: ret=QStringLiteral("bool"); break;
0143         case ExpressionType::List:
0144             ret='['+typesToString(m_contained).join(QStringLiteral("$"))+']';
0145             break;
0146         case ExpressionType::Vector:
0147             ret='<'+typesToString(m_contained).join(QStringLiteral("$"))+','+QString::number(m_size)+'>';
0148             break;
0149         case ExpressionType::Matrix:
0150             ret=QStringLiteral("{%1,%2x%3}").arg(contained().contained().toString()).arg(m_size).arg(contained().size());
0151             break;
0152         case ExpressionType::Error:
0153             ret=QStringLiteral("err");
0154             break;
0155         case ExpressionType::Lambda:
0156             ret=typesToString(m_contained).join(QStringLiteral(" -> "));
0157             break;
0158         case ExpressionType::Any: {
0159 //             ret=QString(m_any, '*');
0160             QString id;
0161             for(int i=m_any; i>0; i/='z'-'a') {
0162                 id.prepend(QChar('a'-1+(i%('z'-'a'))));
0163             }
0164             ret=id;
0165 //             ret+=QString::number(m_any);
0166         }    break;
0167         case ExpressionType::Many:
0168             ret=/*"{"+*/typesToString(m_contained).join(QStringLiteral(" | "))/*+"}"*/;
0169             break;
0170         case ExpressionType::Object:
0171             ret="obj:"+m_objectName;
0172             break;
0173     }
0174     
0175     return ret;
0176 }
0177 
0178 bool ExpressionType::isError() const
0179 {
0180     if(m_type==Error)
0181         return true;
0182     else if(m_type==Many && m_contained.isEmpty())
0183         return true;
0184     foreach (const ExpressionType& t, m_contained) {
0185         if(t.isError())
0186             return true;
0187     }
0188     return false;
0189 }
0190 
0191 ExpressionType ExpressionType::operator=(const ExpressionType& et)
0192 {
0193     if(&et!=this) {
0194         m_type=et.m_type;
0195         m_contained=et.m_contained;
0196         m_size=et.m_size;
0197         m_assumptions=et.m_assumptions;
0198         m_objectName=et.m_objectName;
0199     }
0200     
0201     return *this;
0202 }
0203 
0204 bool ExpressionType::operator==(const ExpressionType& t) const
0205 {
0206 //     qDebug() <<"seeee" << m_type << t.m_type << t.m_contained << m_contained << t << *this;
0207     bool ret=t.m_type==m_type;
0208     ret=ret            && (m_type==ExpressionType::Any ? m_any==t.m_any : (m_size<1 || t.m_size<1 || m_size==t.m_size));
0209     ret=ret            && t.m_contained==m_contained;
0210     
0211     if(!ret && t.type()==ExpressionType::Many && t.alternatives().size()==1)
0212         ret=*this==t.alternatives().at(0);
0213     
0214     if(!ret &&   type()==ExpressionType::Many &&   alternatives().size()==1)
0215         ret=t==alternatives().at(0);
0216     
0217     ret &= m_objectName==t.m_objectName;
0218 //     qDebug() << "++++++++" << t << *this << ret;
0219     return ret;
0220 }
0221 
0222 bool ExpressionType::addAssumption(const QString& bvar, const Analitza::ExpressionType& t)
0223 {
0224     ExpressionType toadd=t;
0225     addAssumptions(t.assumptions());
0226     toadd.clearAssumptions();
0227     
0228     QMap< QString, ExpressionType >::iterator it=m_assumptions.find(bvar);
0229     if(it==m_assumptions.end())
0230         m_assumptions.insert(bvar, toadd);
0231     else {
0232         toadd=minimumType(toadd,*it);
0233         if(toadd.isError())
0234             return false;
0235         *it=toadd;
0236     }
0237     
0238     return true;
0239 }
0240 
0241 void ExpressionType::removeAssumptions(const QStringList& bvarStrings)
0242 {
0243     foreach(const QString& bvar, bvarStrings)
0244         m_assumptions.remove(bvar);
0245     
0246     QList<ExpressionType>::iterator it=m_contained.begin(), itEnd=m_contained.end();
0247     for(; it!=itEnd; ++it) {
0248         it->removeAssumptions(bvarStrings);
0249     }
0250 }
0251 
0252 void ExpressionType::addAssumptions(const QMap<QString, ExpressionType>& a)
0253 {
0254 //     qDebug() << "=====1" << m_assumptions << a;
0255     bool valid=assumptionsMerge(m_assumptions, a);
0256 //     qDebug() << "=====2" << m_assumptions;
0257     Q_ASSERT(valid);
0258 }
0259 
0260 ExpressionType ExpressionType::starsToType(const QMap<int, ExpressionType>& info) const
0261 {
0262 #if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS)
0263     for(QMap<int, ExpressionType>::const_iterator it=info.cbegin(); it!=info.cend(); ++it) {
0264         Q_ASSERT(it->type()!=ExpressionType::Any || it->anyValue()!=it.key());
0265     }
0266 #endif
0267     
0268     ExpressionType ret;
0269 //     static int deep=0;
0270 //     qDebug() << qPrintable("hohohoho"+QString(++deep, '-')) << *this << info << &info;
0271     
0272 //     qDebug() << ".........." << *this << info.keys();
0273     if(m_type==ExpressionType::Any && info.contains(m_any)) {
0274         ret=info.value(m_any);
0275         ret.m_assumptions=m_assumptions;
0276     } else if((m_type==ExpressionType::Vector || m_type==ExpressionType::Matrix) && m_size<0 && info.contains(m_size)) {
0277         ret=*this;
0278         QMap<int, ExpressionType> info2(info);
0279         ExpressionType sometype = info2.take(m_size);
0280         ret.m_size = sometype.m_size;
0281         ret.m_contained.first() = m_contained.first().starsToType(info2);
0282         ret.m_assumptions=m_assumptions;
0283     } else {
0284         ret=*this;
0285         
0286         bool hasMany=false;
0287         for(QList<ExpressionType>::iterator it=ret.m_contained.begin(), itEnd=ret.m_contained.end(); it!=itEnd; ++it) {
0288             *it=it->starsToType(info);
0289             hasMany|=(it->type()==ExpressionType::Many);
0290         }
0291         
0292         if(hasMany) {
0293             QList<ExpressionType> args=manyFromArgs(ret.m_contained);
0294             QList<ExpressionType> alts;
0295             foreach(const ExpressionType& t, args) {
0296                 ExpressionType tt=ret;
0297                 tt.m_contained=t.m_contained;
0298                 
0299                 bool b=assumptionsMerge(tt.m_assumptions, t.m_assumptions);
0300                 if(b)
0301                     alts += tt;
0302             }
0303             ret=ExpressionType(ExpressionType::Many, alts);
0304         }
0305     }
0306     
0307     for(QMap<QString, ExpressionType>::iterator it=ret.m_assumptions.begin(), itEnd=ret.m_assumptions.end(); it!=itEnd; ++it) {
0308         *it=it->starsToType(info);
0309     }
0310     
0311 //     qDebug() << qPrintable("fuuuuuuu"+QString(deep, '-')) << info << &info;
0312     
0313 //     deep--;
0314 //     qDebug() << "MMMMMMMM" << ret << ret.assumptions() << m_assumptions;
0315     
0316     return ret;
0317 }
0318 
0319 bool ExpressionType::canCompareTo(const ExpressionType& type) const
0320 {
0321     bool ret=type==*this;
0322     if(!ret && type.m_type==m_type) {
0323         switch(m_type) {
0324             case ExpressionType::List:
0325                 ret=contained().canCompareTo(type.contained());
0326                 break;
0327             case ExpressionType::Matrix:
0328             case ExpressionType::Vector:
0329                 ret=contained().canCompareTo(type.contained());
0330                 if(ret && m_size>0 && type.m_size>0)
0331                     ret = m_size == type.m_size;
0332                 break;
0333             case ExpressionType::Object:
0334                 ret = m_objectName==type.m_objectName;
0335                 break;
0336             case ExpressionType::Lambda:
0337                 ret = m_contained.size()==type.m_contained.size();
0338                 break;
0339             case ExpressionType::Error:
0340             case ExpressionType::Bool:
0341             case ExpressionType::Char:
0342             case ExpressionType::Value:
0343             case ExpressionType::Any:
0344             case ExpressionType::Many: //todo?
0345                 ret=true;
0346                 break;
0347         }
0348     } else if(!ret)
0349         ret = (m_type==Any || m_type==Error) || (type.m_type==Any || type.m_type==Error);
0350     return ret;
0351 }
0352 
0353 bool ExpressionType::canReduceTo(const ExpressionType& type) const
0354 {
0355     bool ret=false;
0356     
0357     if(type==*this || m_type==Any || isError())
0358         ret=true;
0359     else if(m_type==Many) {
0360         foreach(const ExpressionType& t, m_contained) {
0361             if(t.canReduceTo(type)) {
0362                 ret=true;
0363                 break;
0364             }
0365         }
0366     } else if(type.m_type==Many) {
0367         foreach(const ExpressionType& t, type.m_contained) {
0368             if(canReduceTo(t)) {
0369                 ret=true;
0370                 break;
0371             }
0372         }
0373     } else if(m_type==Lambda) {
0374         ret = m_contained.size()==type.m_contained.size();
0375         QMap<int, ExpressionType> reductionsApplied;
0376         for(int i=0; ret && i<m_contained.size(); i++) {
0377             ExpressionType a=m_contained[i].starsToType(reductionsApplied), b=type.m_contained[i].starsToType(reductionsApplied);
0378             ret&=a.canReduceTo(b);
0379             
0380             if(ret && a.type()==Any && a!=b) {
0381                 b.clearAssumptions();
0382                 reductionsApplied.insert(a.anyValue(), b);
0383             }
0384         }
0385     } else if(m_type==Vector && type.m_type==Vector) {
0386         ret  = m_size<0 || type.m_size<0 || m_size==type.m_size;
0387         ret &= contained().canReduceTo(type.contained());
0388     } else if(m_type==List && type.m_type==List) {
0389         ret = contained().canReduceTo(type.contained());
0390     } else if(m_type==Matrix && type.m_type==Matrix) {
0391         ret = contained().canReduceTo(type.contained());
0392     }
0393     
0394 //     qDebug() << "OOOOOOOOOOOOO" << *this << type << ret;
0395     
0396     return ret;
0397 }
0398 
0399 QMap<QString, ExpressionType> ExpressionType::assumptions() const
0400 {
0401 //     printAssumptions(*this);
0402     return m_assumptions;
0403 }
0404 
0405 QMap< QString, ExpressionType >& ExpressionType::assumptions()
0406 {
0407     return m_assumptions;
0408 }
0409 
0410 int ExpressionType::increaseStars(int stars)
0411 {
0412     int ret=stars;
0413     
0414     if(m_type==ExpressionType::Any) {
0415         m_any=stars+m_any;
0416         if(m_any>ret) 
0417             ret=m_any+1;
0418     }
0419     
0420     for(QList<ExpressionType>::iterator it=m_contained.begin(), itEnd=m_contained.end(); it!=itEnd; ++it) {
0421         ret=qMax(it->increaseStars(stars), ret);
0422     }
0423     
0424     for(QMap<QString,ExpressionType>::iterator it=m_assumptions.begin(), itEnd=m_assumptions.end(); it!=itEnd; ++it) {
0425         ret=qMax(it->increaseStars(stars), ret);
0426     }
0427     
0428     return ret;
0429 }
0430 
0431 void ExpressionType::starsSimplification(ExpressionType& t, QMap<int, int>& reductions, int &next)
0432 {
0433     switch(t.m_type) {
0434         case ExpressionType::Any:
0435             if(reductions.contains(t.m_any))
0436                 t.m_any=reductions.value(t.m_any);
0437             else {
0438                 reductions.insert(t.m_any, next);
0439                 t.m_any=next++;
0440             }
0441             
0442             break;
0443         case ExpressionType::Many:
0444         case ExpressionType::Vector:
0445         case ExpressionType::Matrix:
0446         case ExpressionType::List:
0447         case ExpressionType::Lambda:
0448             for(QList<ExpressionType>::iterator it=t.m_contained.begin(), itEnd=t.m_contained.end(); it!=itEnd; ++it) {
0449                 starsSimplification(*it, reductions, next);
0450             }
0451             break;
0452         case ExpressionType::Object:
0453         case ExpressionType::Value:
0454         case ExpressionType::Char:
0455         case ExpressionType::Bool:
0456         case ExpressionType::Error:
0457             break;
0458     }
0459 }
0460 
0461 ExpressionType& ExpressionType::simplifyStars()
0462 {
0463     int next=1;
0464     QMap<int, int> map;
0465     starsSimplification(*this, map, next);
0466     return *this;
0467 }
0468 
0469 ExpressionType ExpressionType::returnValue() const
0470 {
0471     ExpressionType ret;
0472     
0473     if(m_type==Analitza::ExpressionType::Many) {
0474         ret=ExpressionType(ExpressionType::Many);
0475         foreach(const ExpressionType& t, m_contained)
0476             ret.addAlternative(t.returnValue());
0477     } else if(m_type==Analitza::ExpressionType::Lambda)
0478         ret=m_contained.last();
0479     
0480     return ret;
0481 }
0482 
0483 void ExpressionType::reduce(const Analitza::ExpressionType& type)
0484 {
0485     if(m_type == Many) {
0486         QList<ExpressionType> newcontained;
0487         
0488         foreach(const ExpressionType& t, m_contained) {
0489             if(t.canReduceTo(type))
0490                 newcontained.append(t);
0491         }
0492         
0493         if(newcontained.size()==1) {
0494             bool b=assumptionsMerge(newcontained.first().assumptions(), m_assumptions);
0495             Q_ASSERT(b);
0496             *this = newcontained.first();
0497         } else if(newcontained.isEmpty())
0498             ;
0499         else
0500             m_contained = newcontained;
0501         
0502     }
0503     
0504     if(m_type == Many) {
0505         QList<ExpressionType>::iterator it=m_contained.begin(), itEnd=m_contained.end();
0506         for(; it!=itEnd; ) {
0507             bool b = assumptionsMerge(it->assumptions(), type.assumptions());
0508             
0509 //             qDebug() << "LLLLL" << b << *it << it->assumptions();
0510             if(b)
0511                 ++it;
0512             else
0513                 it=m_contained.erase(it);
0514         }
0515     } else {
0516         bool b = assumptionsMerge(m_assumptions, type.assumptions());
0517         if(!b)
0518             *this = ExpressionType(Error);
0519         else if(m_type==ExpressionType::Any && *this!=type) {
0520             QMap<int, ExpressionType> t;
0521             t.insert(m_any, type);
0522             
0523             QMap<QString, ExpressionType> resassumptions=assumptions();
0524             *this = type.starsToType(t);
0525             addAssumptions(resassumptions);
0526         }
0527     }
0528     
0529     if(m_type==Lambda && type.m_type==Lambda && canReduceTo(type)) {
0530         QList< ExpressionType >::iterator it1=m_contained.begin();
0531         QList< ExpressionType >::const_iterator it2=type.m_contained.constBegin();
0532         
0533         for(; it1!=m_contained.end(); ++it1, ++it2) {
0534             *it1=minimumType(*it1, *it2);
0535         }
0536     }
0537 }
0538 
0539 ExpressionType ExpressionType::minimumType(const ExpressionType& t1, const ExpressionType& t2)
0540 {
0541     if(t1.type()==ExpressionType::Many && t2.type()==ExpressionType::Many) {
0542         QList<ExpressionType> alts;
0543 //         qDebug() << "IIIIIIIIII" << t1 << t2;
0544         foreach(const ExpressionType& alt1, t1.alternatives()) {
0545             foreach(const ExpressionType& alt2, t2.alternatives()) {
0546                 if(alt1.canReduceTo(alt2)) {
0547                     ExpressionType alt(alt1);
0548                     alt.reduce(alt2);
0549                     
0550                     if(!alt.isError()) {
0551                         alts+=alt;
0552                     }
0553                 }
0554             }
0555         }
0556         
0557         if(alts.isEmpty())
0558             return ExpressionType(ExpressionType::Error);
0559         else {
0560 //             qDebug() << "aaaaaaaaaaaaaaaaaaaaaaaaaaa" << alts << "\n\t --- " << alts.first().assumptions() << "\n\t --- " << alts.last().assumptions()
0561 //                         << "\n\t --- " << t1.assumptions() << t2.assumptions();
0562             ExpressionType ret=ExpressionType(ExpressionType::Many, alts);
0563             ret.addAssumptions(t1.assumptions());
0564             ret.addAssumptions(t2.assumptions());
0565             return ret;
0566         }
0567     }
0568     else if(t2.isError())
0569         return t1;
0570     else if(t1.isError())
0571         return t2;
0572     else if(t1.type()==ExpressionType::Any && t2.type()==ExpressionType::Any)
0573         return t1.anyValue()>t2.anyValue() ? t1 : t2;
0574     else if(t1.type()==ExpressionType::Lambda && t2.type()==ExpressionType::Lambda && t1.parameters().size()==t2.parameters().size()) {
0575         ExpressionType t(ExpressionType::Lambda);
0576         for(int i=0; i<t1.parameters().size(); i++) {
0577             t.addParameter(minimumType(t1.parameters().at(i), t2.parameters().at(i)));
0578         }
0579         if(!t.isError()) {
0580             t.addAssumptions(t1.assumptions());
0581             t.addAssumptions(t2.assumptions());
0582         }
0583         
0584         return t;
0585     } else if(t1.canReduceTo(t2)) {
0586 //         qDebug() << "zas" << t1 << t2 << "|||" << t1.assumptions() << t2.assumptions();
0587         ExpressionType t(t2);
0588         t.reduce(t1);
0589 //         qDebug() << "zus" << t << t.assumptions();
0590         return t;
0591     } else if(t2.canReduceTo(t1)) {
0592         ExpressionType t(t1);
0593         t.reduce(t2);
0594         return t;
0595     }
0596     
0597     return ExpressionType();
0598 }
0599 
0600 ExpressionType& ExpressionType::addParameter(const ExpressionType& t)
0601 {
0602     Q_ASSERT(m_type==Lambda);
0603     m_contained.append(t);
0604     return *this;
0605 }
0606 
0607 void ExpressionType::addAlternative(const ExpressionType& t)
0608 {
0609     Q_ASSERT(m_type==Many);
0610     /*int i=m_contained.indexOf(t);
0611     if(i>=0) {
0612         m_contained[i].addAssumptions(t.assumptions());//TODO??
0613     } else */
0614     if(t.m_type==Many) {
0615         foreach(const ExpressionType& tt, t.alternatives()) 
0616             addAlternative(tt);
0617         
0618         addAssumptions(t.m_assumptions);
0619 //         m_contained=t.m_contained;
0620     } else
0621         m_contained.append(t);
0622 }
0623 
0624 void ExpressionType::clearAssumptions()
0625 {
0626     m_assumptions.clear();
0627     QList< ExpressionType >::iterator it=m_contained.begin(), itEnd=m_contained.end();
0628     for(; it!=itEnd; ++it) {
0629         it->clearAssumptions();
0630     }
0631 }
0632 
0633 QMap<int, ExpressionType> ExpressionType::processContained(const QMap<int, ExpressionType>& initial, const ExpressionType& candidate, const ExpressionType& type)
0634 {
0635     auto ret=computeStars(initial, candidate.contained(), type.contained());
0636 
0637     if(candidate.size()<0) {
0638         ExpressionType t=type;
0639         t.m_contained.first()=t.m_contained.first().starsToType(ret);
0640         ret[candidate.size()] = t;
0641     }
0642     return ret;
0643 }
0644 
0645 QMap<int, ExpressionType> ExpressionType::computeStars(const QMap<int, ExpressionType>& initial, const ExpressionType& candidate, const ExpressionType& type)
0646 {
0647     QMap<int, ExpressionType> ret(initial);
0648     
0649     switch(candidate.type()) {
0650         case ExpressionType::Any: {
0651             int stars=candidate.anyValue();
0652             
0653             if(ret.contains(stars)) {
0654                 ExpressionType t=ret.take(stars);
0655                 ret=computeStars(ret, t, type);
0656                 
0657                 t=t.starsToType(ret);
0658                 if(t.type()!=ExpressionType::Any || t.m_any!=stars)
0659                     ret.insert(stars, t);
0660             } else if(type.type()!=ExpressionType::Any || type.m_any!=stars) {
0661                 ret[stars]=type;
0662             }
0663         }    break;
0664         case ExpressionType::List:
0665             if(type.type()==ExpressionType::List) { // remove? assert?
0666                 ret=computeStars(initial, candidate.contained(), type.contained());
0667             }
0668             break;
0669         case ExpressionType::Matrix:
0670             if(type.type()==ExpressionType::Matrix) { // remove? assert?
0671                 ret = processContained(initial, candidate, type);
0672             }
0673             break;
0674         case ExpressionType::Vector:
0675             if(type.type()==ExpressionType::Vector) { // remove?
0676                 ret = processContained(initial, candidate, type);
0677             }
0678             break;
0679         case ExpressionType::Lambda:
0680             if(type.type()!=ExpressionType::Lambda)
0681                 break;
0682             Q_ASSERT(type.parameters().size()==candidate.parameters().size());
0683             for(int i=0; i<type.parameters().size(); i++) {
0684                 ret=computeStars(ret, candidate.parameters().at(i), type.parameters().at(i));
0685             }
0686             break;
0687         case ExpressionType::Many:
0688         case ExpressionType::Object:
0689         case ExpressionType::Value:
0690         case ExpressionType::Bool:
0691         case ExpressionType::Char:
0692         case ExpressionType::Error:
0693 //             Q_ASSERT(false && "bffff");
0694             break;
0695     }
0696     
0697     for(QMap<int, ExpressionType>::iterator it=ret.begin(), itEnd=ret.end(); it!=itEnd; ++it) {
0698         ExpressionType t=it->starsToType(ret);
0699         if(t.type()!=ExpressionType::Any || t.m_any!=it.key()) {
0700             *it=t;
0701         }
0702     }
0703     
0704 //     qDebug() << ";;;;;;;" << candidate.type() << candidate << type << ret;
0705 //     bool b = matchAssumptions(&ret, type.assumptions(), candidate.assumptions());
0706 //     qDebug() << "feeeee" << ret;
0707     
0708     return ret;
0709 }
0710 
0711 bool ExpressionType::matchAssumptions(QMap< int, ExpressionType >* stars,
0712                                                 const QMap< QString, ExpressionType >& assum1,
0713                                                 const QMap< QString, ExpressionType >& assum2)
0714 {
0715     bool ret=true;
0716     QMap<QString, ExpressionType>::const_iterator it=assum1.constBegin(), itEnd=assum1.constEnd();
0717     QMap<QString, ExpressionType>::const_iterator itFind, itFindEnd=assum2.constEnd();
0718     
0719     for(; ret && it!=itEnd; ++it) {
0720         itFind=assum2.find(it.key());
0721         
0722         if(itFind!=itFindEnd && *itFind!=*it) {
0723 //             qDebug() << "sih" << it.key() << *it << *itFind;
0724             if(itFind->canReduceTo(*it))
0725                 *stars=ExpressionType::computeStars(*stars, *itFind, *it);
0726             else if(it->canReduceTo(*itFind))
0727                 *stars=ExpressionType::computeStars(*stars, *it, *itFind);
0728             else
0729                 ret=false;
0730 //             qDebug() << "seh" << *stars << ret;
0731         }
0732     }
0733     
0734     return ret;
0735 }
0736 
0737 QStringList ExpressionType::wrongAssumptions(const QMap< QString, ExpressionType >& assum1, const QMap< QString, ExpressionType >& assum2)
0738 {
0739     QStringList ret;
0740     QMap<QString, ExpressionType>::const_iterator it=assum1.constBegin(), itEnd=assum1.constEnd();
0741     QMap<QString, ExpressionType>::const_iterator itFind, itFindEnd=assum2.constEnd();
0742     
0743     for(; it!=itEnd; ++it) {
0744         itFind=assum2.find(it.key());
0745         
0746         if(itFind!=itFindEnd && *itFind!=*it && !itFind->canReduceTo(*it) && !it->canReduceTo(*itFind)) {
0747             ret += it.key();
0748         }
0749     }
0750     
0751     return ret;
0752 }
0753 
0754 QList<ExpressionType> ExpressionType::manyFromArgs(const QList<ExpressionType>& args)
0755 {
0756     QList<ExpressionType> funcs = QList<ExpressionType>() << ExpressionType(ExpressionType::Many);
0757     
0758     foreach(const ExpressionType& e, args) {
0759         QList<ExpressionType> alts = e.type()==ExpressionType::Many ? e.alternatives() : QList<ExpressionType>() << e;
0760         QList<ExpressionType> newfuncs;
0761         foreach(const ExpressionType& rr, alts) {
0762             foreach(const ExpressionType& f, funcs) {
0763                 newfuncs += f;
0764                 
0765                 QMap<int, ExpressionType> stars;
0766 //                 qDebug() << "&&&&&&&" << rr << newfuncs.last().assumptions() << rr.assumptions();
0767                 bool m=ExpressionType::assumptionsMerge(newfuncs.last().assumptions(), rr.assumptions());
0768                 m|=ExpressionType::matchAssumptions(&stars, newfuncs.last().assumptions(), rr.assumptions());
0769 //                 qDebug() << "falala" << m;
0770                 
0771                 if(m)
0772                     newfuncs.last().addAlternative(rr.starsToType(stars));
0773                 else
0774                     newfuncs.removeLast();
0775             }
0776         }
0777         
0778         funcs = newfuncs;
0779     }
0780     
0781     return funcs;
0782 }
0783 
0784 QList<ExpressionType> ExpressionType::lambdaFromArgs(const QList<ExpressionType>& args)
0785 {
0786     QList<ExpressionType> funcs = QList<ExpressionType>() << ExpressionType(ExpressionType::Lambda);
0787     
0788     foreach(const ExpressionType& e, args) {
0789         QList<ExpressionType> alts = e.type()==ExpressionType::Many ? e.alternatives() : QList<ExpressionType>() << e;
0790         QList<ExpressionType> newfuncs;
0791         foreach(const ExpressionType& rr, alts) {
0792             foreach(const ExpressionType& f, funcs) {
0793                 newfuncs += f;
0794                 
0795                 QMap<int, ExpressionType> stars;
0796 //                 qDebug() << "&&&&&&&" << rr << newfuncs.last().assumptions() << rr.assumptions();
0797                 bool m=ExpressionType::assumptionsMerge(newfuncs.last().assumptions(), rr.assumptions());
0798                 m|=matchAssumptions(&stars, newfuncs.last().assumptions(), rr.assumptions());
0799 //                 qDebug() << "falala" << m;
0800                 
0801                 if(m)
0802                     newfuncs.last().addParameter(rr.starsToType(stars));
0803                 else
0804                     newfuncs.removeLast();
0805             }
0806         }
0807         
0808         funcs = newfuncs;
0809     }
0810     
0811     return funcs;
0812 }
0813 
0814 QString ExpressionType::objectName() const
0815 {
0816     return m_objectName;
0817 }
0818 
0819 bool ExpressionType::hasContained() const
0820 {
0821     Q_ASSERT(m_type==Vector || m_type==List || m_type==Matrix || m_type==Any);
0822     return !m_contained.isEmpty();
0823 }
0824 
0825 ExpressionType ExpressionType::contained() const
0826 {
0827     Q_ASSERT(m_type==Vector || m_type==List || m_type==Matrix || m_type==Any);
0828     Q_ASSERT(m_contained.size()==1);
0829     return m_contained.first();
0830 }