diff --git a/matlab/writeVarExpectationFunction.m b/matlab/writeVarExpectationFunction.m index ec638220b..591fdc197 100644 --- a/matlab/writeVarExpectationFunction.m +++ b/matlab/writeVarExpectationFunction.m @@ -1,11 +1,11 @@ -function writeVarExpectationFunction(var_model_name, dwrt) -%function writeVarExpectationFunction(model_name, dwrt) +function writeVarExpectationFunction(var_model_name) +%function writeVarExpectationFunction(model_name) %% global M_; %% open file -basename = ['var_forecast_' var_model_name '_' dwrt]; +basename = ['var_forecast_' var_model_name]; fid = fopen([basename '.m'], 'w'); if fid == -1 error(['Could not open ' basename '.m for writing']); @@ -20,7 +20,7 @@ end %% fprintf(fid, 'function y = %s(y, h)\n', basename); fprintf(fid, '%%function y = %s(y, h)\n', basename); -fprintf(fid, '%% Calculates the h-step-ahead forecast for %s from the VAR model %s\n', dwrt, var_model_name); +fprintf(fid, '%% Calculates the h-step-ahead forecast from the VAR model %s\n', var_model_name); fprintf(fid, '%%\n%% Created automatically by Dynare\n%%\n\n'); fprintf(fid, '%%%% Construct y\n'); fprintf(fid, 'assert(length(y) == %d);\n', sum(sum(M_.lead_lag_incidence ~= 0))); @@ -57,7 +57,7 @@ if M_.var.(var_model_name).order > 1 end fprintf(fid, '%%%% Calculate h-step-ahead forecast\n'); fprintf(fid, 'for i=1:h\n'); -fprintf(fid, 'y = ['); +fprintf(fid, ' y = ['); fprintf(fid, [repmat(' %f ', 1, size(mu, 2)) ';'], mu'); fprintf(fid, '] + ['); fprintf(fid, [repmat(' %f ', 1, size(A, 2)) ';'], A'); @@ -65,13 +65,13 @@ fprintf(fid, ']*y(:);\n'); fprintf(fid, 'end\n'); fprintf(fid, 'y = y(1:%d);\n', lm); -retidx = find(strcmp(dwrt, endo_names) & yidx == 1); -assert(~isempty(retidx)) -if retidx == 1 - fprintf(fid, 'y = y(1);\n'); -else - fprintf(fid, 'y = y(%d);\n', sum(yidx(1:retidx-1))+1); -end +% retidx = find(strcmp(dwrt, endo_names) & yidx == 1); +% assert(~isempty(retidx)) +% if retidx == 1 +% fprintf(fid, 'y = y(1);\n'); +% else +% fprintf(fid, 'y = y(%d);\n', sum(yidx(1:retidx-1))+1); +% end %% close file fprintf(fid, 'end\n'); diff --git a/preprocessor/CodeInterpreter.hh b/preprocessor/CodeInterpreter.hh index 1c7e195cc..ed695fc27 100644 --- a/preprocessor/CodeInterpreter.hh +++ b/preprocessor/CodeInterpreter.hh @@ -199,8 +199,7 @@ enum UnaryOpcode oSteadyStateParamDeriv, // for the derivative of the STEADY_STATE operator w.r.t. to a parameter oSteadyStateParam2ndDeriv, // for the 2nd derivative of the STEADY_STATE operator w.r.t. to a parameter oExpectation, - oErf, - oVarExpectation + oErf }; enum BinaryOpcode diff --git a/preprocessor/ComputingTasks.cc b/preprocessor/ComputingTasks.cc index 479105920..72a6f75bf 100644 --- a/preprocessor/ComputingTasks.cc +++ b/preprocessor/ComputingTasks.cc @@ -174,16 +174,20 @@ PriorPosteriorFunctionStatement::writeOutput(ostream &output, const string &base VarModelStatement::VarModelStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg, const string &name_arg, - const SymbolTable &symbol_table_arg, - const DynamicModel &dynamic_model_arg) : + const SymbolTable &symbol_table_arg) : symbol_list(symbol_list_arg), options_list(options_list_arg), name(name_arg), - symbol_table(symbol_table_arg), - dynamic_model(dynamic_model_arg) + symbol_table(symbol_table_arg) { } +void +VarModelStatement::getVarModelNameAndVarList(map &var_model_info) +{ + var_model_info[name] = symbol_list; +} + void VarModelStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { @@ -215,8 +219,8 @@ VarModelStatement::writeOutput(ostream &output, const string &basename, bool min options_list.writeOutput(output); symbol_list.writeOutput("options_.var.var_list_", output); output << "M_.var." << name << " = options_.var;" << endl - << "clear options_.var;" << endl; - dynamic_model.writeVarExpectationFunctions(output, name); + << "clear options_.var;" << endl + << "writeVarExpectationFunction('" << name << "');" << endl; } StochSimulStatement::StochSimulStatement(const SymbolList &symbol_list_arg, diff --git a/preprocessor/ComputingTasks.hh b/preprocessor/ComputingTasks.hh index e76ba3aea..7bda35b00 100644 --- a/preprocessor/ComputingTasks.hh +++ b/preprocessor/ComputingTasks.hh @@ -117,13 +117,12 @@ private: const OptionsList options_list; const string &name; const SymbolTable &symbol_table; - const DynamicModel &dynamic_model; public: VarModelStatement(const SymbolList &symbol_list_arg, const OptionsList &options_list_arg, const string &name_arg, - const SymbolTable &symbol_table_arg, - const DynamicModel &dynamic_model_arg); + const SymbolTable &symbol_table_arg); + void getVarModelNameAndVarList(map &var_model_info); virtual void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings); virtual void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const; }; diff --git a/preprocessor/DataTree.cc b/preprocessor/DataTree.cc index ff761c7f5..adaed600b 100644 --- a/preprocessor/DataTree.cc +++ b/preprocessor/DataTree.cc @@ -491,9 +491,15 @@ DataTree::AddExpectation(int iArg1, expr_t iArg2) } expr_t -DataTree::AddVarExpectation(expr_t iArg1, const int iArg2, const string &iArg3) +DataTree::AddVarExpectation(const int symb_id, const int forecast_horizon, const string &model_name) { - return AddUnaryOp(oVarExpectation, iArg1, 0, 0, 0, make_pair(iArg2, iArg3)); + assert(symbol_table.getType(symb_id) == eEndogenous); + + var_expectation_node_map_t::iterator it = var_expectation_node_map.find(make_pair(model_name, make_pair(symb_id, forecast_horizon))); + if (it != var_expectation_node_map.end()) + return it->second; + + return new VarExpectationNode(*this, symb_id, forecast_horizon, model_name); } expr_t diff --git a/preprocessor/DataTree.hh b/preprocessor/DataTree.hh index 53391017f..e7acd6ca3 100644 --- a/preprocessor/DataTree.hh +++ b/preprocessor/DataTree.hh @@ -48,6 +48,7 @@ class DataTree friend class ExternalFunctionNode; friend class FirstDerivExternalFunctionNode; friend class SecondDerivExternalFunctionNode; + friend class VarExpectationNode; protected: //! A reference to the symbol table SymbolTable &symbol_table; @@ -62,7 +63,7 @@ protected: typedef map, VariableNode *> variable_node_map_t; variable_node_map_t variable_node_map; //! Pair( Pair(arg1, UnaryOpCode), Pair( Expectation Info Set, Pair(param1_symb_id, param2_symb_id)) )) - typedef map, pair >, pair > >, UnaryOpNode *> unary_op_node_map_t; + typedef map, pair > >, UnaryOpNode *> unary_op_node_map_t; unary_op_node_map_t unary_op_node_map; //! Pair( Pair( Pair(arg1, arg2), order of Power Derivative), opCode) typedef map, int>, BinaryOpcode>, BinaryOpNode *> binary_op_node_map_t; @@ -74,6 +75,10 @@ protected: typedef map, int>, ExternalFunctionNode *> external_function_node_map_t; external_function_node_map_t external_function_node_map; + // (model_name, (symb_id, forecast_horizon)) -> VarExpectationNode + typedef map >, VarExpectationNode *> var_expectation_node_map_t; + var_expectation_node_map_t var_expectation_node_map; + // ((arguments, deriv_idx), symb_id) -> FirstDerivExternalFunctionNode typedef map, int>, int>, FirstDerivExternalFunctionNode *> first_deriv_external_function_node_map_t; first_deriv_external_function_node_map_t first_deriv_external_function_node_map; @@ -98,7 +103,7 @@ private: int node_counter; inline expr_t AddPossiblyNegativeConstant(double val); - inline expr_t AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set = 0, int param1_symb_id = 0, int param2_symb_id = 0, const pair &var_expectation_pair = make_pair(0,string())); + inline expr_t AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set = 0, int param1_symb_id = 0, int param2_symb_id = 0); inline expr_t AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, int powerDerivOrder = 0); inline expr_t AddTrinaryOp(expr_t arg1, TrinaryOpcode op_code, expr_t arg2, expr_t arg3); @@ -156,8 +161,6 @@ public: expr_t AddPowerDeriv(expr_t iArg1, expr_t iArg2, int powerDerivOrder); //! Adds "E(arg1)(arg2)" to model tree expr_t AddExpectation(int iArg1, expr_t iArg2); - //! Adds "var_expectation(arg1, arg2, model_name=arg3)" to model tree - expr_t AddVarExpectation(expr_t iArg1, const int iArg2, const string &iArg3); //! Adds "exp(arg)" to model tree expr_t AddExp(expr_t iArg1); //! Adds "log(arg)" to model tree @@ -212,6 +215,8 @@ public: expr_t AddSteadyStateParam2ndDeriv(expr_t iArg1, int param1_symb_id, int param2_symb_id); //! Adds "arg1=arg2" to model tree expr_t AddEqual(expr_t iArg1, expr_t iArg2); + //! Adds "var_expectation(arg1, arg2, model_name=arg3)" to model tree + expr_t AddVarExpectation(const int symb_id, const int forecast_horizon, const string &model_name); //! Adds a model local variable with its value void AddLocalVariable(int symb_id, expr_t value) throw (LocalVariableException); //! Adds an external function node @@ -306,10 +311,10 @@ DataTree::AddPossiblyNegativeConstant(double v) } inline expr_t -DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id, const pair &var_expectation_pair) +DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id) { // If the node already exists in tree, share it - unary_op_node_map_t::iterator it = unary_op_node_map.find(make_pair(make_pair(arg, op_code), make_pair(make_pair(arg_exp_info_set, make_pair(param1_symb_id, param2_symb_id)), var_expectation_pair))); + unary_op_node_map_t::iterator it = unary_op_node_map.find(make_pair(make_pair(arg, op_code), make_pair(arg_exp_info_set, make_pair(param1_symb_id, param2_symb_id)))); if (it != unary_op_node_map.end()) return it->second; @@ -328,7 +333,7 @@ DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int { } } - return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id, var_expectation_pair); + return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id); } inline expr_t diff --git a/preprocessor/DynamicModel.cc b/preprocessor/DynamicModel.cc index bb9d0ba9e..ee8ffad8b 100644 --- a/preprocessor/DynamicModel.cc +++ b/preprocessor/DynamicModel.cc @@ -1558,11 +1558,20 @@ DynamicModel::writeDynamicMFile(const string &dynamic_basename) const << "% Warning : this file is generated automatically by Dynare" << endl << "% from model file (.mod)" << endl << endl; + writeVarExpectationCalls(mDynamicModelFile); writeDynamicModel(mDynamicModelFile, false, false); mDynamicModelFile << "end" << endl; // Close *_dynamic function mDynamicModelFile.close(); } +void +DynamicModel::writeVarExpectationCalls(ofstream &output) const +{ + map alreadyWritten; + for (size_t i = 0; i < equations.size(); i++) + equations[i]->writeVarExpectationCalls(output, alreadyWritten); +} + void DynamicModel::writeDynamicJuliaFile(const string &basename) const { @@ -3141,14 +3150,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de output << "];" << endl; } -void -DynamicModel::writeVarExpectationFunctions(ostream &output, const string &var_model_name) const -{ - // Write Var Forecast files - for (int eq = 0; eq < (int) equations.size(); eq++) - equations[eq]->writeVarExpectationFunction(output, var_model_name); -} - map >, expr_t> DynamicModel::collect_first_order_derivatives_endogenous() { @@ -3174,6 +3175,13 @@ DynamicModel::runTrendTest(const eval_context_t &eval_context) testTrendDerivativesEqualToZero(eval_context); } +void +DynamicModel::setVarExpectationIndices(map var_model_info) +{ + for (size_t i = 0; i < equations.size(); i++) + equations[i]->setVarExpectationIndex(var_model_info); +} + void DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, int paramsDerivsOrder, const eval_context_t &eval_context, bool no_tmp_terms, bool block, bool use_dll, diff --git a/preprocessor/DynamicModel.hh b/preprocessor/DynamicModel.hh index 9f0f2994b..5655c454c 100644 --- a/preprocessor/DynamicModel.hh +++ b/preprocessor/DynamicModel.hh @@ -85,6 +85,8 @@ private: void writeDynamicMFile(const string &dynamic_basename) const; //! Writes dynamic model file (Julia version) void writeDynamicJuliaFile(const string &dynamic_basename) const; + //! Write Var Expectation calls + void writeVarExpectationCalls(ofstream &output) const; //! Writes dynamic model file (C version) /*! \todo add third derivatives handling */ void writeDynamicCFile(const string &dynamic_basename, const int order) const; @@ -236,15 +238,15 @@ public: //! Writes model initialization and lead/lag incidence matrix to output void writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll, int order, bool estimation_present, bool compute_xrefs, bool julia) const; - //! Writes calls to functions that write functions that forecast VARs - void writeVarExpectationFunctions(ostream &output, const string &var_model_name) const; - //! Return true if the hessian is equal to zero inline bool checkHessianZero() const; //! Return equations that have non-zero second derivatives void getNonZeroHessianEquations(map &eqs) const; + //! Set indices for var expectation in dynamic model file + void setVarExpectationIndices(map var_model_info); + //! Adds informations for simulation in a binary file void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const; diff --git a/preprocessor/ExprNode.cc b/preprocessor/ExprNode.cc index 0b9f60c1b..4d7296824 100644 --- a/preprocessor/ExprNode.cc +++ b/preprocessor/ExprNode.cc @@ -194,12 +194,6 @@ ExprNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &inst // Nothing to do } -void -ExprNode::writeVarExpectationFunction(ostream &output, const string &var_model_name) const -{ - // Nothing to do -} - VariableNode * ExprNode::createEndoLeadAuxiliaryVarForMyself(subst_table_t &subst_table, vector &neweqs) const { @@ -355,11 +349,6 @@ NumConstNode::collectDynamicVariables(SymbolType type_arg, set > { } -void -NumConstNode::writeVarExpectationFunction(ostream &output, const string &var_model_name) const -{ -} - pair NumConstNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const { @@ -519,6 +508,16 @@ NumConstNode::isInStaticForm() const return true; } +void +NumConstNode::setVarExpectationIndex(map var_model_info) +{ +} + +void +NumConstNode::writeVarExpectationCalls(ofstream &output, map alreadyWritten) const +{ +} + expr_t NumConstNode::substituteStaticAuxiliaryVariable() const { @@ -1405,11 +1404,6 @@ VariableNode::isNumConstNodeEqualTo(double value) const return false; } -void -VariableNode::writeVarExpectationFunction(ostream &output, const string &var_model_name) const -{ -} - bool VariableNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const { @@ -1518,21 +1512,28 @@ VariableNode::isInStaticForm() const return lag == 0; } -UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const pair &var_expectation_arg) : +void +VariableNode::setVarExpectationIndex(map var_model_info) +{ +} + +void +VariableNode::writeVarExpectationCalls(ofstream &output, map alreadyWritten) const +{ +} + +UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg) : ExprNode(datatree_arg), arg(arg_arg), expectation_information_set(expectation_information_set_arg), param1_symb_id(param1_symb_id_arg), param2_symb_id(param2_symb_id_arg), - var_expectation_horizon(var_expectation_arg.first), - var_expectation_model_name(var_expectation_arg.second), op_code(op_code_arg) { // Add myself to the unary op map datatree.unary_op_node_map[make_pair(make_pair(arg, op_code), - make_pair(make_pair(expectation_information_set, - make_pair(param1_symb_id, param2_symb_id)), - var_expectation_arg))] = this; + make_pair(expectation_information_set, + make_pair(param1_symb_id, param2_symb_id)))] = this; } void @@ -1678,21 +1679,11 @@ UnaryOpNode::composeDerivatives(expr_t darg, int deriv_id) t14 = datatree.AddDivide(datatree.Two, t13); // (2/(sqrt(pi)*exp(x^2)))*dx; return datatree.AddTimes(t14, darg); - case oVarExpectation: - return datatree.Zero; } // Suppress GCC warning exit(EXIT_FAILURE); } -void -UnaryOpNode::writeVarExpectationFunction(ostream &output, const string &var_model_name) const -{ - if (op_code == oVarExpectation && var_model_name == var_expectation_model_name) - output << "writeVarExpectationFunction('" << var_expectation_model_name << "', '" - << datatree.symbol_table.getName((dynamic_cast(arg))->symb_id) << "');" << endl; -} - expr_t UnaryOpNode::computeDerivative(int deriv_id) { @@ -1769,8 +1760,6 @@ UnaryOpNode::cost(int cost, bool is_matlab) const case oSteadyStateParam2ndDeriv: case oExpectation: return cost; - case oVarExpectation: - return cost + MIN_COST_MATLAB + 1; } else // Cost for C files @@ -1813,8 +1802,6 @@ UnaryOpNode::cost(int cost, bool is_matlab) const case oSteadyStateParam2ndDeriv: case oExpectation: return cost; - case oVarExpectation: - return cost + MIN_COST_C + 1; } exit(EXIT_FAILURE); } @@ -2040,16 +2027,6 @@ UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, case oErf: output << "erf"; break; - case oVarExpectation: - VariableNode *varg = dynamic_cast(arg); - if (IS_LATEX(output_type)) - output << "VAR" << LEFT_PAR(output_type) - << datatree.symbol_table.getTeXName(varg->symb_id) - << "_{t+" << var_expectation_horizon << "}" << RIGHT_PAR(output_type); - else - output << "var_forecast_" << var_expectation_model_name << "_" - << datatree.symbol_table.getName(varg->symb_id) << "(y, " << var_expectation_horizon << ")"; - return; } bool close_parenthesis = false; @@ -2145,8 +2122,6 @@ UnaryOpNode::eval_opcode(UnaryOpcode op_code, double v) throw (EvalException, Ev case oSteadyStateParamDeriv: case oSteadyStateParam2ndDeriv: case oExpectation: - case oVarExpectation: - throw EvalException(); case oErf: return (erf(v)); } @@ -2398,8 +2373,6 @@ UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) con return alt_datatree.AddExpectation(expectation_information_set, alt_arg); case oErf: return alt_datatree.AddErf(alt_arg); - case oVarExpectation: - return alt_datatree.AddVarExpectation(alt_arg, var_expectation_horizon, var_expectation_model_name); } // Suppress GCC warning exit(EXIT_FAILURE); @@ -2408,9 +2381,6 @@ UnaryOpNode::buildSimilarUnaryOpNode(expr_t alt_arg, DataTree &alt_datatree) con expr_t UnaryOpNode::toStatic(DataTree &static_datatree) const { - if (op_code == oVarExpectation) - return static_datatree.AddVariable((dynamic_cast(arg))->symb_id); - expr_t sarg = arg->toStatic(static_datatree); return buildSimilarUnaryOpNode(sarg, static_datatree); } @@ -2624,6 +2594,18 @@ UnaryOpNode::isInStaticForm() const return arg->isInStaticForm(); } +void +UnaryOpNode::setVarExpectationIndex(map var_model_info) +{ + arg->setVarExpectationIndex(var_model_info); +} + +void +UnaryOpNode::writeVarExpectationCalls(ofstream &output, map alreadyWritten) const +{ + arg->writeVarExpectationCalls(output, alreadyWritten); +} + expr_t UnaryOpNode::substituteStaticAuxiliaryVariable() const { @@ -3121,13 +3103,6 @@ BinaryOpNode::containsExternalFunction() const || arg2->containsExternalFunction(); } -void -BinaryOpNode::writeVarExpectationFunction(ostream &output, const string &var_model_name) const -{ - arg1->writeVarExpectationFunction(output, var_model_name); - arg2->writeVarExpectationFunction(output, var_model_name); -} - void BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -3934,6 +3909,20 @@ BinaryOpNode::isInStaticForm() const return arg1->isInStaticForm() && arg2->isInStaticForm(); } +void +BinaryOpNode::setVarExpectationIndex(map var_model_info) +{ + arg1->setVarExpectationIndex(var_model_info); + arg2->setVarExpectationIndex(var_model_info); +} + +void +BinaryOpNode::writeVarExpectationCalls(ofstream &output, map alreadyWritten) const +{ + arg1->writeVarExpectationCalls(output, alreadyWritten); + arg2->writeVarExpectationCalls(output, alreadyWritten); +} + expr_t BinaryOpNode::substituteStaticAuxiliaryVariable() const { @@ -4267,14 +4256,6 @@ TrinaryOpNode::containsExternalFunction() const || arg3->containsExternalFunction(); } -void -TrinaryOpNode::writeVarExpectationFunction(ostream &output, const string &var_model_name) const -{ - arg1->writeVarExpectationFunction(output, var_model_name); - arg2->writeVarExpectationFunction(output, var_model_name); - arg3->writeVarExpectationFunction(output, var_model_name); -} - void TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -4614,6 +4595,22 @@ TrinaryOpNode::isInStaticForm() const return arg1->isInStaticForm() && arg2->isInStaticForm() && arg3->isInStaticForm(); } +void +TrinaryOpNode::setVarExpectationIndex(map var_model_info) +{ + arg1->setVarExpectationIndex(var_model_info); + arg2->setVarExpectationIndex(var_model_info); + arg3->setVarExpectationIndex(var_model_info); +} + +void +TrinaryOpNode::writeVarExpectationCalls(ofstream &output, map alreadyWritten) const +{ + arg1->writeVarExpectationCalls(output, alreadyWritten); + arg2->writeVarExpectationCalls(output, alreadyWritten); + arg3->writeVarExpectationCalls(output, alreadyWritten); +} + expr_t TrinaryOpNode::substituteStaticAuxiliaryVariable() const { @@ -4921,6 +4918,20 @@ AbstractExternalFunctionNode::isInStaticForm() const return true; } +void +AbstractExternalFunctionNode::setVarExpectationIndex(map var_model_info) +{ + for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) + (*it)->setVarExpectationIndex(var_model_info); +} + +void +AbstractExternalFunctionNode::writeVarExpectationCalls(ofstream &output, map alreadyWritten) const +{ + for (vector::const_iterator it = arguments.begin(); it != arguments.end(); it++) + (*it)->writeVarExpectationCalls(output, alreadyWritten); +} + pair AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const { @@ -4940,14 +4951,6 @@ AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->writeVarExpectationFunction(output, var_model_name); -} - void AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -5848,3 +5851,299 @@ SecondDerivExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileC cerr << "SecondDerivExternalFunctionNode::compileExternalFunctionOutput: not implemented." << endl; exit(EXIT_FAILURE); } + +VarExpectationNode::VarExpectationNode(DataTree &datatree_arg, + int symb_id_arg, + int forecast_horizon_arg, + const string &model_name_arg) : + ExprNode(datatree_arg), + symb_id(symb_id_arg), + forecast_horizon(forecast_horizon_arg), + model_name(model_name_arg), + yidx(-1) +{ + datatree.var_expectation_node_map[make_pair(model_name, make_pair(symb_id, forecast_horizon))] = this; +} + +void +VarExpectationNode::computeTemporaryTerms(map > &reference_count, + map &temp_terms_map, + bool is_matlab, NodeTreeReference tr) const +{ + temp_terms_map[tr].insert(const_cast(this)); +} + +void +VarExpectationNode::computeTemporaryTerms(map &reference_count, + temporary_terms_t &temporary_terms, + map > &first_occurence, + int Curr_block, + vector< vector > &v_temporary_terms, + int equation) const +{ + expr_t this2 = const_cast(this); + temporary_terms.insert(this2); + first_occurence[this2] = make_pair(Curr_block, equation); + v_temporary_terms[Curr_block][equation].insert(this2); +} + +expr_t +VarExpectationNode::toStatic(DataTree &static_datatree) const +{ + return static_datatree.AddVariable(symb_id); +} + +expr_t +VarExpectationNode::cloneDynamic(DataTree &dynamic_datatree) const +{ + return dynamic_datatree.AddVarExpectation(symb_id, forecast_horizon, model_name); +} + +void +VarExpectationNode::writeOutput(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + assert(output_type != oMatlabOutsideModel); + + if (IS_LATEX(output_type)) + { + output << "VAR_" << model_name << LEFT_PAR(output_type) + << datatree.symbol_table.getTeXName(symb_id) + << "_{t+" << forecast_horizon << "}" << RIGHT_PAR(output_type); + return; + } + + // If current node is a temporary term + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + if (output_type == oMatlabDynamicModelSparse) + output << "T" << idx << "(it_)"; + else + output << "T" << idx; + return; + } + + output << "dynamic_var_forecast_" << model_name << "_" << forecast_horizon << "(" << yidx + 1 << ")"; +} + +void +VarExpectationNode::writeVarExpectationCalls(ofstream &output, map alreadyWritten) const +{ + map::iterator it = alreadyWritten.find(model_name); + if (it != alreadyWritten.end() && alreadyWritten[model_name] == forecast_horizon) + return; + + output << "dynamic_var_forecast_" << model_name << "_" << forecast_horizon << " = " + << "var_forecast_" << model_name << "(y, " << forecast_horizon << ");" << endl; + alreadyWritten[model_name] = forecast_horizon; +} + +int +VarExpectationNode::maxEndoLead() const +{ + return 0; +} + +int +VarExpectationNode::maxExoLead() const +{ + return 0; +} + +int +VarExpectationNode::maxEndoLag() const +{ + return 0; +} + +int +VarExpectationNode::maxExoLag() const +{ + return 0; +} + +int +VarExpectationNode::maxLead() const +{ + return 0; +} + +expr_t +VarExpectationNode::decreaseLeadsLags(int n) const +{ + return const_cast(this); +} + +void +VarExpectationNode::prepareForDerivation() +{ + preparedForDerivation = true; + // All derivatives are null, so non_null_derivatives is left empty +} + +expr_t +VarExpectationNode::computeDerivative(int deriv_id) +{ + return datatree.Zero; +} + +expr_t +VarExpectationNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) +{ + return datatree.Zero; +} + +bool +VarExpectationNode::containsExternalFunction() const +{ + return false; +} + +double +VarExpectationNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) +{ + eval_context_t::const_iterator it = eval_context.find(symb_id); + if (it == eval_context.end()) + throw EvalException(); + + return it->second; +} + +void +VarExpectationNode::computeXrefs(EquationInfo &ei) const +{ +} + +void +VarExpectationNode::collectDynamicVariables(SymbolType type_arg, set > &result) const +{ +} + +void +VarExpectationNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const +{ + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + temporary_terms_inuse.insert(idx); +} + +void +VarExpectationNode::compile(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const +{ + cerr << "VarExpectationNode::compile not implemented." << endl; + exit(EXIT_FAILURE); +} + +pair +VarExpectationNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const +{ + return make_pair(0, datatree.AddVariableInternal(symb_id, 0)); +} + +expr_t +VarExpectationNode::substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +{ + return const_cast(this); +} + +expr_t +VarExpectationNode::substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const +{ + return const_cast(this); +} + +expr_t +VarExpectationNode::substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const +{ + return const_cast(this); +} + +expr_t +VarExpectationNode::substituteExoLag(subst_table_t &subst_table, vector &neweqs) const +{ + return const_cast(this); +} + +expr_t +VarExpectationNode::substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const +{ + return const_cast(this); +} + +expr_t +VarExpectationNode::differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const +{ + return const_cast(this); +} + +bool +VarExpectationNode::containsEndogenous(void) const +{ + return true; +} + +bool +VarExpectationNode::containsExogenous() const +{ + return false; +} + +bool +VarExpectationNode::isNumConstNodeEqualTo(double value) const +{ + return false; +} + +expr_t +VarExpectationNode::decreaseLeadsLagsPredeterminedVariables() const +{ + return const_cast(this); +} + +bool +VarExpectationNode::isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const +{ + return false; +} + +expr_t +VarExpectationNode::replaceTrendVar() const +{ + return const_cast(this); +} + +expr_t +VarExpectationNode::detrend(int symb_id, bool log_trend, expr_t trend) const +{ + return const_cast(this); +} + +expr_t +VarExpectationNode::removeTrendLeadLag(map trend_symbols_map) const +{ + return const_cast(this); +} + +bool +VarExpectationNode::isInStaticForm() const +{ + return false; +} + +void +VarExpectationNode::setVarExpectationIndex(map var_model_info) +{ + vector vs = var_model_info[model_name].get_symbols();; + yidx= find(vs.begin(), vs.end(), datatree.symbol_table.getName(symb_id)) - vs.begin(); +} + +expr_t +VarExpectationNode::substituteStaticAuxiliaryVariable() const +{ + return const_cast(this); +} diff --git a/preprocessor/ExprNode.hh b/preprocessor/ExprNode.hh index f8f809f58..5021c96cb 100644 --- a/preprocessor/ExprNode.hh +++ b/preprocessor/ExprNode.hh @@ -30,6 +30,7 @@ using namespace std; #include "SymbolTable.hh" #include "CodeInterpreter.hh" #include "ExternalFunctionsTable.hh" +#include "SymbolList.hh" class DataTree; class VariableNode; @@ -135,6 +136,7 @@ class ExprNode friend class BinaryOpNode; friend class TrinaryOpNode; friend class AbstractExternalFunctionNode; + friend class VarExpectationNode; private: //! Computes derivative w.r. to a derivation ID (but doesn't store it in derivatives map) /*! You shoud use getDerivative() to get the benefit of symbolic a priori and of caching */ @@ -212,9 +214,6 @@ public: //! returns true if the expr node contains an external function virtual bool containsExternalFunction() const = 0; - //! Writes the matlab/C function for a Var Expectation Node - virtual void writeVarExpectationFunction(ostream &output, const string &var_model_name) const = 0; - //! Writes output of node (with no temporary terms and with "outside model" output type) void writeOutput(ostream &output) const; @@ -452,6 +451,12 @@ public: //! Substitute auxiliary variables by their expression in static model virtual expr_t substituteStaticAuxiliaryVariable() const = 0; + + // Add index information for var_model variables + virtual void setVarExpectationIndex(map var_model_info) = 0; + + // Write calls to var forecast and place in temporary variable + virtual void writeVarExpectationCalls(ofstream &output, map) const = 0; }; //! Object used to compare two nodes (using their indexes) @@ -504,7 +509,6 @@ public: virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; - virtual void writeVarExpectationFunction(ostream &output, const string &var_model_name) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -513,6 +517,8 @@ public: virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; + virtual void setVarExpectationIndex(map var_model_info); + virtual void writeVarExpectationCalls(ofstream &output, map) const; virtual expr_t substituteStaticAuxiliaryVariable() const; }; @@ -571,7 +577,6 @@ public: virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; - virtual void writeVarExpectationFunction(ostream &output, const string &var_model_name) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -580,6 +585,8 @@ public: virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; + virtual void setVarExpectationIndex(map var_model_info); + virtual void writeVarExpectationCalls(ofstream &output, map) const; //! Substitute auxiliary variables by their expression in static model virtual expr_t substituteStaticAuxiliaryVariable() const; }; @@ -593,9 +600,6 @@ private: const int expectation_information_set; //! Only used for oSteadyStateParamDeriv and oSteadyStateParam2ndDeriv const int param1_symb_id, param2_symb_id; - //! Only used for oVarExpectation - const int var_expectation_horizon; - const string var_expectation_model_name; const UnaryOpcode op_code; virtual expr_t computeDerivative(int deriv_id); virtual int cost(int cost, bool is_matlab) const; @@ -604,7 +608,7 @@ private: //! Returns the derivative of this node if darg is the derivative of the argument expr_t composeDerivatives(expr_t darg, int deriv_id); public: - UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const pair &var_expectation_arg); + UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg); virtual void prepareForDerivation(); virtual void computeTemporaryTerms(map > &reference_count, map &temp_terms_map, @@ -661,7 +665,6 @@ public: virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; - virtual void writeVarExpectationFunction(ostream &output, const string &var_model_name) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -670,6 +673,8 @@ public: virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; + virtual void setVarExpectationIndex(map var_model_info); + virtual void writeVarExpectationCalls(ofstream &output, map) const; //! Substitute auxiliary variables by their expression in static model virtual expr_t substituteStaticAuxiliaryVariable() const; }; @@ -761,7 +766,6 @@ public: virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; - virtual void writeVarExpectationFunction(ostream &output, const string &var_model_name) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -776,6 +780,8 @@ public: //! Returns the non-zero hand-side of an equation (that must have a hand side equal to zero) expr_t getNonZeroPartofEquation() const; virtual bool isInStaticForm() const; + virtual void setVarExpectationIndex(map var_model_info); + virtual void writeVarExpectationCalls(ofstream &output, map) const; //! Substitute auxiliary variables by their expression in static model virtual expr_t substituteStaticAuxiliaryVariable() const; //! Substitute auxiliary variables by their expression in static model auxiliary variable definition @@ -843,7 +849,6 @@ public: virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; - virtual void writeVarExpectationFunction(ostream &output, const string &var_model_name) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -852,6 +857,8 @@ public: virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; + virtual void setVarExpectationIndex(map var_model_info); + virtual void writeVarExpectationCalls(ofstream &output, map) const; //! Substitute auxiliary variables by their expression in static model virtual expr_t substituteStaticAuxiliaryVariable() const; }; @@ -925,7 +932,6 @@ public: virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; virtual bool isNumConstNodeEqualTo(double value) const; - virtual void writeVarExpectationFunction(ostream &output, const string &var_model_name) const; virtual bool containsEndogenous(void) const; virtual bool containsExogenous() const; virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; @@ -935,6 +941,8 @@ public: virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const = 0; virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; virtual bool isInStaticForm() const; + virtual void setVarExpectationIndex(map var_model_info); + virtual void writeVarExpectationCalls(ofstream &output, map) const; //! Substitute auxiliary variables by their expression in static model virtual expr_t substituteStaticAuxiliaryVariable() const; }; @@ -1046,4 +1054,64 @@ public: virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; }; +class VarExpectationNode : public ExprNode +{ +private: + const int symb_id; + const int forecast_horizon; + const string &model_name; + int yidx; +public: + VarExpectationNode(DataTree &datatree_arg, int symb_id_arg, int forecast_horizon_arg, const string &model_name); + virtual void computeTemporaryTerms(map > &reference_count, + map &temp_terms_map, + bool is_matlab, NodeTreeReference tr) const; + virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual void computeTemporaryTerms(map &reference_count, + temporary_terms_t &temporary_terms, + map > &first_occurence, + int Curr_block, + vector< vector > &v_temporary_terms, + int equation) const; + virtual expr_t toStatic(DataTree &static_datatree) const; + virtual expr_t cloneDynamic(DataTree &dynamic_datatree) const; + virtual int maxEndoLead() const; + virtual int maxExoLead() const; + virtual int maxEndoLag() const; + virtual int maxExoLag() const; + virtual int maxLead() const; + virtual expr_t decreaseLeadsLags(int n) const; + virtual void prepareForDerivation(); + virtual expr_t computeDerivative(int deriv_id); + virtual expr_t getChainRuleDerivative(int deriv_id, const map &recursive_variables); + virtual bool containsExternalFunction() const; + virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); + virtual void computeXrefs(EquationInfo &ei) const; + virtual expr_t substituteEndoLeadGreaterThanTwo(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; + virtual expr_t substituteEndoLagGreaterThanTwo(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substituteExoLead(subst_table_t &subst_table, vector &neweqs, bool deterministic_model) const; + virtual expr_t substituteExoLag(subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t substituteExpectation(subst_table_t &subst_table, vector &neweqs, bool partial_information_model) const; + virtual pair normalizeEquation(int symb_id_endo, vector > > &List_of_Op_RHS) const; + virtual void compile(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const; + virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; + virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; + virtual bool containsEndogenous(void) const; + virtual bool containsExogenous() const; + virtual bool isNumConstNodeEqualTo(double value) const; + virtual expr_t differentiateForwardVars(const vector &subset, subst_table_t &subst_table, vector &neweqs) const; + virtual expr_t decreaseLeadsLagsPredeterminedVariables() const; + virtual bool isVariableNodeEqualTo(SymbolType type_arg, int variable_id, int lag_arg) const; + virtual expr_t replaceTrendVar() const; + virtual expr_t detrend(int symb_id, bool log_trend, expr_t trend) const; + virtual expr_t removeTrendLeadLag(map trend_symbols_map) const; + virtual bool isInStaticForm() const; + virtual void setVarExpectationIndex(map var_model_info); + virtual void writeVarExpectationCalls(ofstream &output, map) const; + virtual expr_t substituteStaticAuxiliaryVariable() const; +}; + #endif diff --git a/preprocessor/ModFile.cc b/preprocessor/ModFile.cc index 975b0d8af..a6e180e45 100644 --- a/preprocessor/ModFile.cc +++ b/preprocessor/ModFile.cc @@ -411,6 +411,18 @@ ModFile::transformPass(bool nostrict, bool compute_xrefs) exit(EXIT_FAILURE); } + // Var Model + map var_model_info; + for (vector::const_iterator it = statements.begin(); + it != statements.end(); it++) + { + VarModelStatement *vms = dynamic_cast(*it); + if (vms != NULL) + vms->getVarModelNameAndVarList(var_model_info); + } + if (!var_model_info.empty()) + dynamic_model.setVarExpectationIndices(var_model_info); + // Freeze the symbol table symbol_table.freeze(); diff --git a/preprocessor/ParsingDriver.cc b/preprocessor/ParsingDriver.cc index 1e27fdd0a..9c5c04093 100644 --- a/preprocessor/ParsingDriver.cc +++ b/preprocessor/ParsingDriver.cc @@ -1286,7 +1286,7 @@ ParsingDriver::var_model() if (it == options_list.string_options.end()) error("You must pass the model_name option to the var_model statement."); const string *name = new string(it->second); - mod_file->addStatement(new VarModelStatement(symbol_list, options_list, *name, mod_file->symbol_table, mod_file->dynamic_model)); + mod_file->addStatement(new VarModelStatement(symbol_list, options_list, *name, mod_file->symbol_table)); symbol_list.clear(); options_list.clear(); } @@ -1628,15 +1628,6 @@ ParsingDriver::copy_options(string *to_declaration_type, string *to_name1, strin delete from_subsample_name; } -void -ParsingDriver::check_symbol_is_endogenous(string *name) -{ - check_symbol_existence(*name); - int symb_id = mod_file->symbol_table.getID(*name); - if (mod_file->symbol_table.getType(symb_id) != eEndogenous) - error(*name + " is not endogenous"); -} - void ParsingDriver::check_symbol_is_endogenous_or_exogenous(string *name) { @@ -2398,8 +2389,7 @@ ParsingDriver::add_expectation(string *arg1, expr_t arg2) expr_t ParsingDriver::add_var_expectation(string *arg1, string *arg2, string *arg3) { - check_symbol_is_endogenous(arg1); - expr_t varExpectationNode = data_tree->AddVarExpectation(add_model_variable(arg1), stoi(*arg2), *arg3); + expr_t varExpectationNode = data_tree->AddVarExpectation(mod_file->symbol_table.getID(*arg1), stoi(*arg2), *arg3); delete arg2; return varExpectationNode; } diff --git a/preprocessor/ParsingDriver.hh b/preprocessor/ParsingDriver.hh index 423b22b0e..98297ae31 100644 --- a/preprocessor/ParsingDriver.hh +++ b/preprocessor/ParsingDriver.hh @@ -87,9 +87,6 @@ private: //! Checks that a given symbol exists and is a parameter, and stops with an error message if it isn't void check_symbol_is_parameter(string *name); - //! Checks that a given symbol exists and is endogenous, and stops with an error message if it isn't - void check_symbol_is_endogenous(string *name); - //! Checks that a given symbol was assigned within a Statement void check_symbol_is_statement_variable(string *name);