From 122e15476413ddf670f2729ebfbb4fdea941f8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Tue, 31 Jul 2018 12:42:08 +0200 Subject: [PATCH] PlannerObjectiveStatement now owns its model_tree By the way, error out if the planner_objective statement is used two times. --- src/ComputingTasks.cc | 26 ++++++++++---------------- src/ComputingTasks.hh | 18 +++++++----------- src/ModFile.cc | 19 +++++++++++++------ src/ParsingDriver.cc | 7 +++++-- src/ParsingDriver.hh | 5 +++++ 5 files changed, 40 insertions(+), 35 deletions(-) diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc index 01b848a3..c54f5ced 100644 --- a/src/ComputingTasks.cc +++ b/src/ComputingTasks.cc @@ -2231,22 +2231,16 @@ ModelComparisonStatement::writeJsonOutput(ostream &output) const output << "}"; } -PlannerObjectiveStatement::PlannerObjectiveStatement(StaticModel *model_tree_arg) : - model_tree(model_tree_arg), - computing_pass_called(false) +PlannerObjectiveStatement::PlannerObjectiveStatement(SymbolTable &symbol_table, NumericalConstants &num_constants, ExternalFunctionsTable &external_functions_table) : + model_tree{symbol_table, num_constants, external_functions_table} { } -PlannerObjectiveStatement::~PlannerObjectiveStatement() -{ - delete model_tree; -} - void PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) { - assert(model_tree->equation_number() == 1); - if (model_tree->exoPresentInEqs()) + assert(model_tree.equation_number() == 1); + if (model_tree.exoPresentInEqs()) { cerr << "ERROR: You cannot include exogenous variables in the planner objective. Please " << "define an auxiliary endogenous variable like eps_aux=epsilon and use it instead " @@ -2256,8 +2250,8 @@ PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct, WarningC mod_file_struct.planner_objective_present = true; } -StaticModel * -PlannerObjectiveStatement::getPlannerObjective() const +StaticModel & +PlannerObjectiveStatement::getPlannerObjective() { return model_tree; } @@ -2265,14 +2259,14 @@ PlannerObjectiveStatement::getPlannerObjective() const void PlannerObjectiveStatement::computingPass() { - model_tree->computingPass({}, false, true, true, 0, false, false, false); + model_tree.computingPass({}, false, true, true, 0, false, false, false); computing_pass_called = true; } void PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const { - model_tree->writeStaticFile(basename + ".objective", false, false, false, false); + model_tree.writeStaticFile(basename + ".objective", false, false, false, false); } void @@ -2281,9 +2275,9 @@ PlannerObjectiveStatement::writeJsonOutput(ostream &output) const output << "{\"statementName\": \"planner_objective\"" << ", "; if (computing_pass_called) - model_tree->writeJsonComputingPassOutput(output, false); + model_tree.writeJsonComputingPassOutput(output, false); else - model_tree->writeJsonOutput(output); + model_tree.writeJsonOutput(output); output << "}"; } diff --git a/src/ComputingTasks.hh b/src/ComputingTasks.hh index f6615f1d..dda5b198 100644 --- a/src/ComputingTasks.hh +++ b/src/ComputingTasks.hh @@ -534,19 +534,15 @@ public: void writeJsonOutput(ostream &output) const override; }; -/*! \todo Make model_tree a member instead of a pointer */ class PlannerObjectiveStatement : public Statement { private: - StaticModel *model_tree; - bool computing_pass_called; + StaticModel model_tree; + bool computing_pass_called{false}; public: - //! Constructor - /*! \param model_tree_arg the model tree used to store the objective function. - It is owned by the PlannerObjectiveStatement, and will be deleted by its destructor */ - PlannerObjectiveStatement(StaticModel *model_tree_arg); - - ~PlannerObjectiveStatement() override; + PlannerObjectiveStatement(SymbolTable &symbol_table, + NumericalConstants &num_constants, + ExternalFunctionsTable &external_functions_table); /*! \todo check there are only endogenous variables at the current period in the objective (no exogenous, no lead/lag) */ void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override; @@ -554,8 +550,8 @@ public: void computingPass() override; void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override; void writeJsonOutput(ostream &output) const override; - //! Return the Planner Objective - StaticModel *getPlannerObjective() const; + //! Return a reference the Planner Objective model tree + StaticModel &getPlannerObjective(); }; class BVARDensityStatement : public Statement diff --git a/src/ModFile.cc b/src/ModFile.cc index cd8af1f9..b62db9d0 100644 --- a/src/ModFile.cc +++ b/src/ModFile.cc @@ -466,14 +466,21 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const mod_file_struct.orig_eq_nbr = dynamic_model.equation_number(); if (mod_file_struct.ramsey_model_present) { - StaticModel *planner_objective = nullptr; + PlannerObjectiveStatement *pos = nullptr; for (auto & statement : statements) { - auto *pos = dynamic_cast<PlannerObjectiveStatement *>(statement); - if (pos != nullptr) - planner_objective = pos->getPlannerObjective(); + auto pos2 = dynamic_cast<PlannerObjectiveStatement *>(statement); + if (pos2 != nullptr) + if (pos != nullptr) + { + cerr << "ERROR: there can only be one planner_objective statement" << endl; + exit(EXIT_FAILURE); + } + else + pos = pos2; } - assert(planner_objective != nullptr); + assert(pos != nullptr); + const StaticModel &planner_objective = pos->getPlannerObjective(); /* clone the model then clone the new equations back to the original because @@ -482,7 +489,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, const if (linear) dynamic_model.cloneDynamic(orig_ramsey_dynamic_model); dynamic_model.cloneDynamic(ramsey_FOC_equations_dynamic_model); - ramsey_FOC_equations_dynamic_model.computeRamseyPolicyFOCs(*planner_objective, nopreprocessoroutput); + ramsey_FOC_equations_dynamic_model.computeRamseyPolicyFOCs(planner_objective, nopreprocessoroutput); ramsey_FOC_equations_dynamic_model.replaceMyEquations(dynamic_model); mod_file_struct.ramsey_eq_nbr = dynamic_model.equation_number() - mod_file_struct.orig_eq_nbr; } diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc index 65b9b62c..9975f746 100644 --- a/src/ParsingDriver.cc +++ b/src/ParsingDriver.cc @@ -2082,7 +2082,9 @@ ParsingDriver::run_model_comparison() void ParsingDriver::begin_planner_objective() { - set_current_data_tree(new StaticModel(mod_file->symbol_table, mod_file->num_constants, mod_file->external_functions_table)); + planner_objective_statement = new PlannerObjectiveStatement(mod_file->symbol_table, mod_file->num_constants, mod_file->external_functions_table); + + set_current_data_tree(&planner_objective_statement->getPlannerObjective()); } void @@ -2092,7 +2094,8 @@ ParsingDriver::end_planner_objective(expr_t expr) expr_t eq = model_tree->AddEqual(expr, model_tree->Zero); model_tree->addEquation(eq, location.begin.line); - mod_file->addStatement(new PlannerObjectiveStatement(dynamic_cast<StaticModel *>(model_tree))); + mod_file->addStatement(planner_objective_statement); + planner_objective_statement = nullptr; // The object is now owned by mod_file reset_data_tree(); } diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh index 0c51e7c1..1b3de334 100644 --- a/src/ParsingDriver.hh +++ b/src/ParsingDriver.hh @@ -110,7 +110,12 @@ private: //! Stores temporary symbol table SymbolList symbol_list; + //! Temporary store for the planner objective + PlannerObjectiveStatement *planner_objective_statement; + //! The data tree in which to add expressions currently parsed + /*! The object pointed to is not owned by the parsing driver. It is essentially a + reference. */ DataTree *data_tree; //! The model tree in which to add expressions currently parsed -- GitLab