00001
00002
00003
00004 #include "mgr.h"
00005 #include "common.h"
00006 #include "var.h"
00007 #include "ast.h"
00008 #include "ui.h"
00009 #include "tplate.h"
00010 #include "func.h"
00011 #include "model.h"
00012 #include "settings.h"
00013 #include "logic.h"
00014 #include "lexer.h"
00015 #include "eparser.h"
00016
00017 #include <stdlib.h>
00018 #include <ctype.h>
00019 #include <algorithm>
00020 #include <memory>
00021 #include <set>
00022
00023 using namespace std;
00024
00025 VariableManager::VariableManager(const Ftk* F)
00026 : F_(F),
00027 var_autoname_counter_(0),
00028 func_autoname_counter_(0)
00029 {
00030 }
00031
00032 VariableManager::~VariableManager()
00033 {
00034 purge_all_elements(functions_);
00035 purge_all_elements(variables_);
00036 }
00037
00038 void VariableManager::unregister_model(const Model *s)
00039 {
00040 vector<Model*>::iterator k = find(models_.begin(), models_.end(), s);
00041 assert (k != models_.end());
00042 models_.erase(k);
00043 }
00044
00045 void VariableManager::sort_variables()
00046 {
00047 for (vector<Variable*>::iterator i = variables_.begin();
00048 i != variables_.end(); ++i)
00049 (*i)->set_var_idx(variables_);
00050 int pos = 0;
00051 while (pos < size(variables_)) {
00052 int M = variables_[pos]->get_max_var_idx();
00053 if (M > pos) {
00054 swap(variables_[pos], variables_[M]);
00055 for (vector<Variable*>::iterator i = variables_.begin();
00056 i != variables_.end(); ++i)
00057 (*i)->set_var_idx(variables_);
00058 }
00059 else
00060 ++pos;
00061 }
00062 }
00063
00064
00065
00066
00067
00068 string VariableManager::get_or_make_variable(const VMData* vd)
00069 {
00070 int ret;
00071 if (vd->index != -1) {
00072 ret = vd->index;
00073 }
00074 else {
00075 ret = next_var_name();
00076 assign_variable(ret, func);
00077 }
00078 assert(is_index(ret, variables_));
00079 return ret;
00080 }
00081 */
00082
00083 Variable* make_compound_variable(const string &name, VMData* vd,
00084 const vector<Variable*>& all_variables)
00085 {
00086 if (vd->has_op(OP_X))
00087 throw ExecuteError("variable can't depend on x.");
00088
00089 vector<string> symbols(all_variables.size());
00090 for (size_t i = 0; i != all_variables.size(); ++i)
00091 symbols[i] = all_variables[i]->name;
00092
00093
00094
00095 vector<string> used_vars;
00096 vm_foreach (int, i, vd->get_mutable_code()) {
00097 if (*i == OP_SYMBOL) {
00098 ++i;
00099 const string& name = all_variables[*i]->name;
00100 int idx = index_of_element(used_vars, name);
00101 if (idx == -1) {
00102 idx = used_vars.size();
00103 used_vars.push_back(name);
00104 }
00105 *i = idx;
00106 }
00107 else if (VMData::has_idx(*i))
00108 ++i;
00109 }
00110
00111 vector<OpTree*> op_trees = prepare_ast_with_der(*vd, used_vars.size());
00112 return new Variable(name, used_vars, op_trees);
00113 }
00114
00115 int VariableManager::make_variable(const string &name, VMData* vd)
00116 {
00117 Variable *var;
00118 assert(!name.empty());
00119 const std::vector<int>& code = vd->code();
00120
00121
00122 if (code.size() == 3 && code[0] == OP_TILDE && code[1] == OP_NUMBER) {
00123 realt val = vd->numbers()[code[2]];
00124
00125 int old_pos = find_variable_nr(name);
00126 if (old_pos != -1 && variables_[old_pos]->is_simple()) {
00127 int nr = variables_[old_pos]->get_nr();
00128 parameters_[nr] = val;
00129 return old_pos;
00130 }
00131
00132 var = new Variable(name, parameters_.size());
00133 parameters_.push_back(val);
00134 }
00135
00136
00137 else {
00138
00139 vector<int>& code = vd->get_mutable_code();
00140 vm_foreach (int, op, code) {
00141 if (*op == OP_TILDE) {
00142 *op = OP_SYMBOL;
00143 ++op;
00144 assert(*op == OP_NUMBER);
00145 *op = variables_.size();
00146 int num_index = *(op+1);
00147 double value = vd->numbers()[num_index];
00148 code.erase(op+1);
00149 string tname = next_var_name();
00150 Variable *tilde_var = new Variable(tname, parameters_.size());
00151 parameters_.push_back(value);
00152 variables_.push_back(tilde_var);
00153 }
00154 else if (VMData::has_idx(*op))
00155 ++op;
00156 }
00157
00158 var = make_compound_variable(name, vd, variables_);
00159 }
00160 return add_variable(var);
00161 }
00162
00163 bool VariableManager::is_variable_referred(int i, string *first_referrer)
00164 {
00165
00166 for (int j = i+1; j < size(variables_); ++j) {
00167 if (variables_[j]->is_directly_dependent_on(i)) {
00168 if (first_referrer)
00169 *first_referrer = "$" + variables_[j]->name;
00170 return true;
00171 }
00172 }
00173 for (vector<Function*>::iterator j = functions_.begin();
00174 j != functions_.end(); ++j) {
00175 if ((*j)->is_directly_dependent_on(i)) {
00176 if (first_referrer)
00177 *first_referrer = "%" + (*j)->name;
00178 return true;
00179 }
00180 }
00181 return false;
00182 }
00183
00184 vector<string>
00185 VariableManager::get_variable_references(const string &name) const
00186 {
00187 int idx = find_variable_nr(name);
00188 vector<string> refs;
00189 v_foreach (Variable*, i, variables_)
00190 if ((*i)->is_directly_dependent_on(idx))
00191 refs.push_back("$" + (*i)->name);
00192 v_foreach (Function*, i, functions_)
00193 for (int j = 0; j < (*i)->get_vars_count(); ++j)
00194 if ((*i)->get_var_idx(j) == idx)
00195 refs.push_back("%" + (*i)->name + "." + (*i)->get_param(j));
00196 return refs;
00197 }
00198
00199
00200 void VariableManager::reindex_all()
00201 {
00202 for (vector<Variable*>::iterator i = variables_.begin();
00203 i != variables_.end(); ++i)
00204 (*i)->set_var_idx(variables_);
00205 for (vector<Function*>::iterator i = functions_.begin();
00206 i != functions_.end(); ++i) {
00207 (*i)->set_var_idx(variables_);
00208 }
00209 }
00210
00211 void VariableManager::remove_unreferred()
00212 {
00213
00214 for (int i = variables_.size()-1; i >= 0; --i)
00215 if (variables_[i]->is_auto_delete()) {
00216 if (!is_variable_referred(i)) {
00217 delete variables_[i];
00218 variables_.erase(variables_.begin() + i);
00219 }
00220 }
00221
00222
00223 reindex_all();
00224
00225
00226 for (int i = size(parameters_)-1; i >= 0; --i) {
00227 bool del=true;
00228 for (int j = 0; j < size(variables_); ++j)
00229 if (variables_[j]->get_nr() == i) {
00230 del=false;
00231 break;
00232 }
00233 if (del) {
00234 parameters_.erase(parameters_.begin() + i);
00235
00236 for (vector<Variable*>::iterator j = variables_.begin();
00237 j != variables_.end(); ++j)
00238 (*j)->erased_parameter(i);
00239 for (vector<Function*>::iterator j = functions_.begin();
00240 j != functions_.end(); ++j)
00241 (*j)->erased_parameter(i);
00242 }
00243 }
00244 }
00245
00246
00247 int VariableManager::add_variable(Variable* new_var)
00248 {
00249 auto_ptr<Variable> var(new_var);
00250 var->set_var_idx(variables_);
00251 int pos = find_variable_nr(var->name);
00252 if (pos == -1) {
00253 pos = variables_.size();
00254 variables_.push_back(var.release());
00255 }
00256 else {
00257 if (var->is_dependent_on(pos, variables_)) {
00258 throw ExecuteError("loop in dependencies of $" + var->name);
00259 }
00260 delete variables_[pos];
00261 variables_[pos] = var.release();
00262 if (variables_[pos]->get_max_var_idx() > pos)
00263 sort_variables();
00264 remove_unreferred();
00265 }
00266 return pos;
00267 }
00268
00269 string VariableManager::assign_variable_copy(const Variable* orig,
00270 const map<int,string>& varmap)
00271 {
00272 string name = name_var_copy(orig);
00273 Variable *var;
00274 if (orig->is_simple()) {
00275 realt val = orig->get_value();
00276 parameters_.push_back(val);
00277 int nr = parameters_.size() - 1;
00278 var = new Variable(name, nr);
00279 }
00280 else {
00281 vector<string> vars;
00282 for (int i = 0; i != orig->get_vars_count(); ++i) {
00283 int v_idx = orig->get_var_idx(i);
00284 assert(varmap.count(v_idx));
00285 vars.push_back(varmap.find(v_idx)->second);
00286 }
00287 vector<OpTree*> new_op_trees;
00288 v_foreach (OpTree*, i, orig->get_op_trees())
00289 new_op_trees.push_back((*i)->clone());
00290 var = new Variable(name, vars, new_op_trees);
00291 }
00292 add_variable(var);
00293 return name;
00294 }
00295
00296
00297 void VariableManager::delete_variables(const vector<string> &names)
00298 {
00299 if (names.empty())
00300 return;
00301
00302 set<int> nn;
00303
00304 v_foreach (string, i, names) {
00305 if (i->find('*') == string::npos) {
00306 int k = find_variable_nr(*i);
00307 if (k == -1)
00308 throw ExecuteError("undefined variable: $" + *i);
00309 nn.insert(k);
00310 }
00311 else
00312 for (size_t j = 0; j != variables_.size(); ++j)
00313 if (match_glob(variables_[j]->name.c_str(), i->c_str()))
00314 nn.insert(j);
00315 }
00316
00317
00318
00319 for (set<int>::const_reverse_iterator i = nn.rbegin(); i != nn.rend(); ++i){
00320
00321 string first_referrer;
00322 if (is_variable_referred(*i, &first_referrer)) {
00323 reindex_all();
00324 remove_unreferred();
00325 throw ExecuteError("can't delete $" + get_variable(*i)->name +
00326 " because " + first_referrer + " depends on it.");
00327 }
00328
00329 delete variables_[*i];
00330 variables_.erase(variables_.begin() + *i);
00331 }
00332
00333
00334 reindex_all();
00335 remove_unreferred();
00336 }
00337
00338 void VariableManager::delete_funcs(const vector<string>& names)
00339 {
00340 if (names.empty())
00341 return;
00342
00343 set<int> nn;
00344
00345 v_foreach (string, i, names) {
00346 if (i->find('*') == string::npos) {
00347 int k = find_function_nr(*i);
00348 if (k == -1)
00349 throw ExecuteError("undefined function: %" + *i);
00350 nn.insert(k);
00351 }
00352 else
00353 for (size_t j = 0; j != functions_.size(); ++j)
00354 if (match_glob(functions_[j]->name.c_str(), i->c_str()))
00355 nn.insert(j);
00356 }
00357
00358
00359 for (set<int>::const_reverse_iterator i = nn.rbegin(); i != nn.rend(); ++i){
00360 delete functions_[*i];
00361 functions_.erase(functions_.begin() + *i);
00362 }
00363
00364
00365 remove_unreferred();
00366 update_indices_in_models();
00367 }
00368
00369 bool VariableManager::is_function_referred(int n) const
00370 {
00371 v_foreach (Model*, i, models_) {
00372 if (contains_element((*i)->get_ff().idx, n)
00373 || contains_element((*i)->get_zz().idx, n))
00374 return true;
00375 }
00376 return false;
00377 }
00378
00379
00380 void VariableManager::auto_remove_functions()
00381 {
00382 int func_size = functions_.size();
00383 for (int i = func_size - 1; i >= 0; --i)
00384 if (functions_[i]->is_auto_delete() && !is_function_referred(i)) {
00385 delete functions_[i];
00386 functions_.erase(functions_.begin() + i);
00387 }
00388 if (func_size != size(functions_)) {
00389 remove_unreferred();
00390 }
00391 }
00392
00393 int VariableManager::find_function_nr(const string &name) const
00394 {
00395 for (int i = 0; i < size(functions_); ++i)
00396 if (functions_[i]->name == name)
00397 return i;
00398 return -1;
00399 }
00400
00401 const Function* VariableManager::find_function(const string &name) const
00402 {
00403 int n = find_function_nr(name);
00404 if (n == -1)
00405 throw ExecuteError("undefined function: %" + name);
00406 return functions_[n];
00407 }
00408
00409 int VariableManager::find_variable_nr(const string &name) const
00410 {
00411 for (int i = 0; i < size(variables_); ++i)
00412 if (variables_[i]->name == name)
00413 return i;
00414 return -1;
00415 }
00416
00417 const Variable* VariableManager::find_variable(const string &name) const
00418 {
00419 int n = find_variable_nr(name);
00420 if (n == -1)
00421 throw ExecuteError("undefined variable: $" + name);
00422 return variables_[n];
00423 }
00424
00425 int VariableManager::find_nr_var_handling_param(int p) const
00426 {
00427 assert(p >= 0 && p < size(parameters_));
00428 for (size_t i = 0; i < variables_.size(); ++i)
00429 if (variables_[i]->get_nr() == p)
00430 return i;
00431 assert(0);
00432 return 0;
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 void VariableManager::use_parameters()
00446 {
00447 use_external_parameters(parameters_);
00448 }
00449
00450 void VariableManager::use_external_parameters(const vector<realt> &ext_param)
00451 {
00452 vm_foreach (Variable*, i, variables_)
00453 (*i)->recalculate(variables_, ext_param);
00454 vm_foreach (Function*, i, functions_)
00455 (*i)->do_precomputations(variables_);
00456 }
00457
00458 void VariableManager::put_new_parameters(const vector<realt> &aa)
00459 {
00460 for (size_t i = 0; i < min(aa.size(), parameters_.size()); ++i)
00461 parameters_[i] = aa[i];
00462 use_parameters();
00463 }
00464
00465 int VariableManager::assign_func(const string &name, Tplate::Ptr tp,
00466 vector<VMData*> &args)
00467 {
00468 assert(tp);
00469 vector<string> varnames;
00470 vm_foreach (VMData*, j, args) {
00471 int idx = (*j)->single_symbol() ? (*j)->code()[1]
00472 : make_variable(next_var_name(), *j);
00473 varnames.push_back(variables_[idx]->name);
00474 }
00475 Function *func = (*tp->create)(F_->get_settings(), name, tp, varnames);
00476 func->init();
00477 return add_func(func);
00478 }
00479
00480 int VariableManager::assign_func_copy(const string &name, const string &orig)
00481 {
00482 assert(!name.empty());
00483 const Function* of = find_function(orig);
00484 map<int,string> var_copies;
00485 for (int i = 0; i < size(variables_); ++i) {
00486 if (of->is_dependent_on(i, variables_)) {
00487 const Variable* var_orig = variables_[i];
00488 var_copies[i] = assign_variable_copy(var_orig, var_copies);
00489 }
00490 }
00491 vector<string> varnames;
00492 for (int i = 0; i != of->get_vars_count(); ++i) {
00493 int v_idx = of->get_var_idx(i);
00494 assert(var_copies.count(v_idx));
00495 varnames.push_back(var_copies[v_idx]);
00496 }
00497
00498 Tplate::Ptr tp = of->tp();
00499 Function* func = (*tp->create)(F_->get_settings(), name, tp, varnames);
00500 func->init();
00501 return add_func(func);
00502 }
00503
00504 int VariableManager::add_func(Function* func)
00505 {
00506 func->set_var_idx(variables_);
00507
00508 int nr = find_function_nr(func->name);
00509 if (nr != -1) {
00510 delete functions_[nr];
00511 functions_[nr] = func;
00512 remove_unreferred();
00513 F_->msg("%" + func->name + " replaced.");
00514 }
00515 else {
00516 nr = functions_.size();
00517 functions_.push_back(func);
00518 F_->msg("%" + func->name + " created.");
00519 }
00520 return nr;
00521 }
00522
00523 string VariableManager::name_var_copy(const Variable* v)
00524 {
00525 if (v->name[0] == '_')
00526 return next_var_name();
00527
00528
00529 int vs = v->name.size();
00530 int appendix = 0;
00531 string core = v->name;
00532 if (vs > 2 && is_int(string(v->name, vs-2, 2))) {
00533 appendix = atoi(v->name.c_str()+vs-2);
00534 core.resize(vs-2);
00535 }
00536 while (true) {
00537 ++appendix;
00538 string new_varname = core + S(appendix/10) + S(appendix%10);
00539 if (find_variable_nr(new_varname) == -1)
00540 return new_varname;
00541 }
00542 }
00543
00544 void VariableManager::substitute_func_param(const string &name,
00545 const string ¶m,
00546 VMData* vd)
00547 {
00548 int nr = find_function_nr(name);
00549 if (nr == -1)
00550 throw ExecuteError("undefined function: %" + name);
00551 Function* k = functions_[nr];
00552 string new_param;
00553 int v_idx = vd->single_symbol() ? vd->code()[1]
00554 : make_variable(next_var_name(), vd);
00555 k->substitute_param(k->get_param_nr(param), variables_[v_idx]->name);
00556 k->set_var_idx(variables_);
00557 remove_unreferred();
00558 }
00559
00560 realt VariableManager::variation_of_a(int n, realt variat) const
00561 {
00562 assert (0 <= n && n < size(parameters()));
00563 const RealRange& dom = get_variable(n)->domain;
00564 if (dom.from_inf() || dom.to_inf()) {
00565 double ctr = get_variable(n)->get_value();
00566 double sigma = ctr * F_->get_settings()->domain_percent / 100.;
00567 return ctr + sigma * variat;
00568 }
00569 else {
00570
00571 return dom.from + 0.5 * (variat + 1) * (dom.to - dom.from);
00572 }
00573 }
00574
00575 string VariableManager::next_var_name()
00576 {
00577 while (1) {
00578 string t = "_" + S(++var_autoname_counter_);
00579 if (find_variable_nr(t) == -1)
00580 return t;
00581 }
00582 }
00583
00584 string VariableManager::next_func_name()
00585 {
00586 while (1) {
00587 string t = "_" + S(++func_autoname_counter_);
00588 if (find_function_nr(t) == -1)
00589 return t;
00590 }
00591 }
00592
00593 void VariableManager::do_reset()
00594 {
00595 purge_all_elements(functions_);
00596 purge_all_elements(variables_);
00597 var_autoname_counter_ = 0;
00598 func_autoname_counter_ = 0;
00599 parameters_.clear();
00600
00601 update_indices_in_models();
00602 }
00603
00604 void VariableManager::update_indices(FunctionSum& sum)
00605 {
00606 sum.idx.clear();
00607 size_t i = 0;
00608 while (i < sum.names.size()) {
00609 int k = find_function_nr(sum.names[i]);
00610 if (k == -1)
00611 sum.names.erase(sum.names.begin() + i);
00612 else {
00613 sum.idx.push_back(k);
00614 ++i;
00615 }
00616 }
00617 }
00618
00619 void VariableManager::update_indices_in_models()
00620 {
00621 for (vector<Model*>::iterator i = models_.begin(); i != models_.end(); ++i){
00622 update_indices((*i)->get_ff());
00623 update_indices((*i)->get_zz());
00624 }
00625 }