diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc index 46214752..8cf7f930 100644 --- a/src/ComputingTasks.cc +++ b/src/ComputingTasks.cc @@ -20,6 +20,8 @@ #include #include #include +#include +#include using namespace std; @@ -1401,6 +1403,41 @@ AbstractEstimatedParamsStatement::commonCheckPass() const } } } + + /* Check that a parameter declared in this block is not used in expressions + associated to other parameters in the same block (see issue #77) */ + // First compute the symbol IDs of parameters declared in this block + set declared_params; + transform(already_declared.begin(), already_declared.end(), inserter(declared_params, declared_params.end()), + [&](const string &name) { return symbol_table.getID(name); }); + // Then look for (apparently) recursive definitions + for (const auto &it : estim_params_list) + { + set used_params; + it.init_val->collectVariables(SymbolType::parameter, used_params); + it.low_bound->collectVariables(SymbolType::parameter, used_params); + it.up_bound->collectVariables(SymbolType::parameter, used_params); + it.mean->collectVariables(SymbolType::parameter, used_params); + it.std->collectVariables(SymbolType::parameter, used_params); + it.p3->collectVariables(SymbolType::parameter, used_params); + it.p4->collectVariables(SymbolType::parameter, used_params); + it.jscale->collectVariables(SymbolType::parameter, used_params); + vector intersect; + set_intersection(declared_params.begin(), declared_params.end(), + used_params.begin(), used_params.end(), + back_inserter(intersect)); + if (intersect.size() > 0) + { + cerr << "ERROR: in `" << blockName() << "' block, the value of estimated parameter " + << symbol_table.getName(intersect[0]) << " is used in the declaration for "; + if (it.type == 3) + cerr << "correlation between " << it.name << " and " << it.name2; + else // either a parameter, the stderr of an exo, or the measurement error of an endo + cerr << "symbol " << it.name; + cerr << ". This behaviour is undefined." << endl; + exit(EXIT_FAILURE); + } + } } EstimatedParamsStatement::EstimatedParamsStatement(vector estim_params_list_arg,