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; }
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); }
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; }
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; } }
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; }