Object* SubstituteExpression::walkApply(const Apply* pattern) { Apply* ret = new Apply; Apply::const_iterator it=pattern->firstValue(), itEnd=pattern->constEnd(); ret->ulimit()=walk(pattern->ulimit()); ret->dlimit()=walk(pattern->dlimit()); ret->domain()=walk(pattern->domain()); PushValue<QStringList> v(m_bvars, m_bvars); QVector<Ci*> bvars = pattern->bvarCi(); foreach(Ci* bvar, bvars) { Ci* nbvar = bvar->copy(); const QString name = bvar->name(); const Object* val = m_values.value(bvar->name()); if(val && !m_renames.contains(name)) { Q_ASSERT(val->type()==Object::variable); QString newname = static_cast<const Ci*>(val)->name(); m_renames.insert(name, newname); } nbvar->setName(solveRename(name)); ret->addBVar(nbvar); m_bvars.append(nbvar->name()); }
bool Analitza::hasVars(Object *o, QString var) { Q_ASSERT(o); //FIXME: Must recognize bvars bool r=false; switch(o->type()) { case Object::variable: if(!var.isEmpty()) { Ci *i = (Ci*) o; r=i->name()==var; } else r=true; break; case Object::container: { Container *c = (Container*) o; QList<Object*>::iterator it = c->m_params.begin(); for(; !r && it!=c->m_params.end(); it++) r |= hasVars(*it); } break; case Object::none: case Object::value: case Object::oper: r=false; } return r; }
bool Analitza::isFunction(Ci func) const { if(!m_vars->contains(func.name())) return false; Container *c = (Container*) m_vars->value(func.name()); return (c && c->type()==Object::container && c->containerType() == Object::lambda); }
Cn Analitza::calc(Object* root) { Q_ASSERT(root && root->type()!=Object::none); Cn ret=Cn(0.); Ci *a; switch(root->type()) { case Object::container: ret = operate((Container*) root); break; case Object::value: ret=(Cn*) root; break; case Object::variable: a=(Ci*) root; if(m_vars->contains(a->name())) ret = calc(m_vars->value(a->name())); else if(a->isFunction()) m_err << i18n("The function <em>%1</em> doesn't exist").arg(a->name()); else m_err << i18n("The variable <em>%1</em> doesn't exist").arg(a->name()); break; case Object::oper: default: break; } return ret; }
void objectWalker(const Object* root, int ind) { Container *c; Cn *num; Operator *op; Ci *var; QString s; if(!root) { qDebug() << "This is an null object"; return; } if(ind>100) return; for(int i=0; i<ind; i++) s += " |_____"; switch(root->type()) { //TODO: include the function into a module and use toString case Object::container: c= (Container*) root; qDebug() << qPrintable(s) << "| cont: " << c->toMathML(); for(int i=0; i<c->m_params.count(); i++) objectWalker(c->m_params[i], ind+1); break; case Object::value: num= (Cn*) root; qDebug() << qPrintable(s) << "| num: " << num->value(); break; case Object::oper: op= (Operator*) root; qDebug() << qPrintable(s) << "| operator: " << op->toString(); break; case Object::variable: var = (Ci*) root; qDebug() << qPrintable(s) << "| variable: " << var->name() << "Func:" << var->isFunction(); break; default: qDebug() << qPrintable(s) << "| dunno: " << (int) root->type(); break; } }
QString Container::toString() const { QStringList ret; bool func=false; Operator *op=0; for(int i=0; i<m_params.count(); i++) { if(m_params[i]==0) { qDebug() << "kkk"; return "<<kk>>"; } if(m_params[i]->type() == Object::oper) op = (Operator*) m_params[i]; else if(m_params[i]->type() == Object::variable) { Ci *b = (Ci*) m_params[i]; if(b->isFunction()) func=true; ret << b->toString(); } else if(m_params[i]->type() == Object::container) { Container *c = (Container*) m_params[i]; QString s = c->toString(); Operator child_op = c->firstOperator(); if(op!=0 && op->weight()>child_op.weight() && child_op.nparams()!=1) s=QString("(%1)").arg(s); if(c->containerType() == Object::bvar) { Container *ul = ulimit(), *dl = dlimit(); if(ul!=0 || dl!=0) { if(dl!=0) s += dl->toString(); s += ".."; if(ul!=0) s += ul->toString(); } } if(c->containerType()!=Object::uplimit && c->containerType()!=Object::downlimit) ret << s; } else ret << m_params[i]->toString(); } QString toret; switch(containerType()) { case Object::declare: toret += ret.join(":="); break; case Object::lambda: toret += ret.join(""); break; case Object::math: toret += ret.join("; "); break; case Object::apply: if(func){ QString n = ret.takeFirst(); toret += QString("%1(%2)").arg(n).arg(ret.join(", ")); } else if(op==0) toret += ret.join(" "); else switch(op->operatorType()) { case Object::plus: toret += ret.join("+"); break; case Object::times: toret += ret.join("*"); break; case Object::divide: toret += ret.join("/"); break; case Object::minus: if(ret.count()==1) toret += "-"+ret[0]; else toret += ret.join("-"); break; case Object::power: toret += ret.join("^"); break; default: toret += QString("%1(%2)").arg(op->toString()).arg(ret.join(", ")); break; } break; case Object::uplimit: //x->(n1..n2) is put at the same time case Object::downlimit: break; case Object::bvar: toret += ret.join("->")+"->"; break; default: toret += ret.join(" ?? "); break; } return toret; }
void basicOps(char* s) { cout << "------- " << s << " -------" << endl; typedef ContainerOfInt Ci; Ci c; print(c, "c after default constructor"); Ci c2(10, 1); // 10 elements, values all 1 print(c2, "c2 after constructor(10,1)"); int ia[] = {1, 3, 5, 7, 9}; const int IASZ = sizeof(ia) / sizeof(*ia); // Initialize with begin & end iterators: Ci c3(ia, ia + IASZ); print(c3, "c3 after constructor(iter, iter)"); Ci c4(c2); // copy-constructor print(c4, "c4 after copy-constructor(c2)"); c = c2; // Assignment operator print(c, "c after operator=c2"); c.assign(10, 2); // 10 elments, values all 2 print(c, "c after assign(10, 2)"); // Assign with begin & end iterators: c.assign(ia, ia + IASZ); print(c, "c after assign iter, iter)"); cout << "c using reverse iterators:" << endl; typename Ci::reverse_iterator rit = c.rbegin(); while (rit != c.rend()) cout << *rit++ << " "; cout << endl; c.resize(4); print(c, "c after resize(4)"); c.push_back(47); print(c, "c after push_back()"); c.pop_back(); print(c, "c after pop_back()"); typename Ci::iterator it = c.begin(); ++it; ++it; c.insert(it, 74); print(c, "c after insert(it, 74)"); it = c.begin(); ++it; c.insert(it, 3, 96); print(c, "c after insert(it, 3, 96)"); it = c.begin(); ++it; c.insert(it, c3.begin(), c3.end()); print(c, "c after insert(" "it, c3.begin(), c3.end())"); it = c.begin(); ++it; c.erase(it); print(c, "c after erase(it)"); typename Ci::iterator it2 = it = c.begin(); ++it; ++it2; ++it2; ++it2; ++it2; ++it2; c.erase(it, it2); print(c, "c after erase(it, it2)"); c.swap(c2); print(c, "c after swap(c2)"); c.clear(); print(c, "c after clear()"); }
Cn Analitza::operate(Container* c) { Q_ASSERT(c); Operator *op=0; Cn ret(0.); QList<Cn> numbers; if(c->containerType() > 100) qDebug() << "wow"; if(c->m_params.isEmpty()) { m_err << i18n("Empty container: %1").arg(c->containerType()); return Cn(0.); } if(c->m_params[0]->type() == Object::oper) op = (Operator*) c->m_params[0]; if(op!= 0 && op->operatorType()==Object::sum) ret = sum(*c); else if(op!= 0 && op->operatorType()==Object::product) ret = product(*c); else switch(c->containerType()) { case Object::apply: case Object::math: case Object::bvar: case Object::uplimit: case Object::downlimit: { if(c->m_params[0]->type() == Object::variable) { Ci* var= (Ci*) c->m_params[0]; if(var->isFunction()) ret = func(c); else ret = calc(c->m_params[0]); } else { QList<Object*>::iterator it = c->m_params.begin(); for(; it!=c->m_params.end(); it++) { if((*it)==0) { m_err << i18n("Null Object found"); ret.setCorrect(false); return ret; } else if((*it)->type() != Object::oper) { numbers.append(calc(*it)); } } if(op==0) { ret = numbers.first(); } else if(op->nparams()>-1 && numbers.count()!=op->nparams() && op->operatorType()!=Object::minus) { m_err << i18n("Too much operators for <em>%1</em>").arg(op->operatorType()); ret = Cn(0.); } else if(numbers.count()>=1 && op->type()==Object::oper) { if(numbers.count()>=2) { QList<Cn>::iterator it = numbers.begin(); ret = *it; ++it; for(; it != numbers.end(); ++it) reduce(op->operatorType(), &ret, *it, false); } else { ret=numbers.first(); reduce(op->operatorType(), &ret, 0., true); } } else { ret = numbers.first(); } } } break; case Object::declare: { if(c->m_params.count()<=1) { m_err << i18n("Need a var name and a value"); return Cn(0.); } Ci *var = (Ci*) c->m_params[0]; switch(c->m_params[1]->type()) { case Object::variable: m_vars->modify(var->name(), new Ci(c->m_params[1])); break; case Object::value: m_vars->modify(var->name(), new Cn(c->m_params[1])); break; case Object::oper: m_vars->modify(var->name(), new Operator(c->m_params[1])); break; case Object::container: m_vars->modify(var->name(), new Container(c->m_params[1])); break; case Object::none: m_err << i18n("Unvalid var type"); break; } } break; case Object::lambda: ret = calc(c->m_params[c->m_params.count()-1]); break; case Object::cnone: break; } return ret; }