/* * Copyright © 2006-2023 Dynare Team * * This file is part of Dynare. * * Dynare is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Dynare is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Dynare. If not, see . */ #ifndef MOD_FILE_HH #define MOD_FILE_HH #include #include #include #include #include #include "Configuration.hh" #include "DynamicModel.hh" #include "ExtendedPreprocessorTypes.hh" #include "ExternalFunctionsTable.hh" #include "ModelEquationBlock.hh" #include "NumericalConstants.hh" #include "NumericalInitialization.hh" #include "Statement.hh" #include "StaticModel.hh" #include "SubModel.hh" #include "SymbolTable.hh" #include "WarningConsolidation.hh" using namespace std; //! The abstract representation of a "mod" file class ModFile { public: explicit ModFile(WarningConsolidation& warnings_arg); //! Symbol table SymbolTable symbol_table; //! External Functions table ExternalFunctionsTable external_functions_table; //! Numerical constants table NumericalConstants num_constants; //! Var Model Table used for storing info about VAR models VarModelTable var_model_table; //! Trend Component Model Table used for storing info about trend component models TrendComponentModelTable trend_component_model_table; //! Table for storing the models declared with var_expectation_model VarExpectationModelTable var_expectation_model_table; //! PAC Model Table used for storing info about pac models PacModelTable pac_model_table; //! Expressions outside model block DataTree expressions_tree; //! Original model, as declared in the "model" block, that won't be modified by the preprocessor DynamicModel original_model; //! Dynamic model, as declared in the "model" block DynamicModel dynamic_model; //! A copy of Dynamic model, for testing trends declared by user DynamicModel trend_dynamic_model; //! A copy of the original model, used to test model linearity under ramsey problem OrigRamseyDynamicModel orig_ramsey_dynamic_model; //! Epilogue model, as declared in the "epilogue" block Epilogue epilogue; //! Static model, as derived from the "model" block when leads and lags have been removed StaticModel static_model; //! Static model, as declared in the "steady_state_model" block if present SteadyStateModel steady_state_model; //! Option linear bool linear {false}; //! Was the “block” option passed to the “model” block? bool block {false}; //! Is the model stored in bytecode format (bytecode=true) or in a M-file (bytecode=false) bool bytecode {false}; /*! Is the model stored in a MEX file ? (option “use_dll”, either in the “model” block or on the preprocessor command line) */ bool use_dll {false}; //! Is the static model have to computed (no_static=false) or not (no_static=true). Option of //! 'model' bool no_static {false}; //! Is the 'differentiate_forward_vars' option used? bool differentiate_forward_vars {false}; /*! If the 'differentiate_forward_vars' option is used, contains the set of endogenous with respect to which to do the transformation; if empty, means that the transformation must be applied to all endos with a lead */ vector differentiate_forward_vars_subset; //! Are nonstationary variables present ? bool nonstationary_variables {false}; //! Global evaluation context /*! Filled using initval blocks and parameters initializations */ eval_context_t global_eval_context; //! Parameter used with lead/lag bool param_used_with_lead_lag {false}; //! Stores the list of extra files to be transefered during a parallel run /*! (i.e. option parallel_local_files of model block) */ vector parallel_local_files; private: //! List of statements vector> statements; //! Structure of the mod file ModFileStructure mod_file_struct; //! Warnings Encountered WarningConsolidation& warnings; //! Functions used in writing of JSON outut. See writeJsonOutput void writeJsonOutputParsingCheck(const string& basename, JsonFileOutputType json_output_mode, bool transformpass, bool computingpass) const; void writeJsonComputingPassOutput(const string& basename, JsonFileOutputType json_output_mode, bool jsonderivsimple) const; void writeJsonFileHelper(const filesystem::path& fname, ostringstream& output) const; /* Generate a random temporary path, in the current directory. Equivalent to boost::filesystem::unique_path(). Both are insecure, but currently there is no better portable solution. Maybe in a later C++ standard? */ static filesystem::path unique_path(); /* Hack for removing a directory that is locked by MATLAB/Windows. The directory is renamed before being deleted. The renaming must occur in the same directory, otherwise it may fail if the destination is not on the same filesystem. This technique is applied recursively to subdirectories. Works even if the argument does not exist or is not a directory. */ static void remove_directory_with_matlab_lock(const filesystem::path& dir); public: //! Add a statement void addStatement(unique_ptr st); //! Add a statement at the front of the statements vector void addStatementAtFront(unique_ptr st); //! Evaluate all the statements /*! \param warn_uninit Should a warning be displayed for uninitialized * endogenous/exogenous/parameters ? */ void evalAllExpressions(bool warn_uninit); //! Do some checking and fills mod_file_struct /*! \todo add check for number of equations and endogenous if ramsey_policy is present */ void checkPass(bool nostrict, bool stochastic); //! Perform some transformations on the model (creation of auxiliary vars and equations) /*! \param compute_xrefs if true, equation cross references will be computed */ void transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool transform_unary_ops, const string& exclude_eqs, const string& include_eqs); //! Execute computations /*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic * files */ /*! \param params_derivs_order compute this order of derivs wrt parameters */ void computingPass(bool no_tmp_terms, OutputType output, int params_derivs_order); //! Writes Matlab/Octave output files /*! \param basename The base name used for writing output files. Should be the name of the mod file without its extension \param clear_all Should a "clear all" instruction be written to output ? \param console Are we in console mode ? \param nograph Should we build the figures? \param nointeractive Should Dynare request user input? \param cygwin Should the MEX command of use_dll be adapted for Cygwin? \param msvc Should the MEX command of use_dll be adapted for MSVC? \param mingw Should the MEX command of use_dll be adapted for MinGW? \param compute_xrefs if true, equation cross references will be computed */ void writeMOutput(const string& basename, bool clear_all, bool clear_global, bool no_warn, bool console, bool nograph, bool nointeractive, const Configuration& config, bool check_model_changes, bool minimal_workspace, bool compute_xrefs, const string& mexext, const filesystem::path& matlabroot, bool onlymodel, bool gui, bool notime) const; void writeJuliaOutput(const string& basename) const; void computeChecksum(); //! Write JSON representation of ModFile object //! Initially created to enable Julia to work with .mod files //! Potentially outputs ModFile after the various parts of processing (parsing, checkPass, //! transformPass, computingPass) Allows user of other host language platforms (python, fortran, //! etc) to provide support for dynare .mod files void writeJsonOutput(const string& basename, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple = false); }; #endif