From 1e77f7c5a72f7f03cbdb81bd60c0c43f8ffa12c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org> Date: Fri, 28 Jan 2022 16:28:14 +0100 Subject: [PATCH] SymbolTable::getOrigSymbIdForAuxVar() now also works on unaryOp and diffForward auxvars This is a more natural semantics. Incidentally, this fixes a bug in the variable mapping (M_.mapping) where some endogenous, appearing in a log() in a VAR or TCM, would not be mentioned (e.g. in the var-expectations/7/example1.mod test, and many others). --- src/DynamicModel.cc | 16 +++++----------- src/ExprNode.cc | 2 +- src/SubModel.cc | 2 +- src/SymbolTable.cc | 6 ++++-- src/SymbolTable.hh | 8 +++----- 5 files changed, 14 insertions(+), 20 deletions(-) diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index e65a6bb2..5717f017 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -3139,7 +3139,7 @@ DynamicModel::updateVarAndTrendModel() const if (!var) { int lhs_symb_id = lhs[lhs_idx++]; - if (symbol_table.isAuxiliaryVariable(lhs_symb_id)) + if (symbol_table.isDiffAuxiliaryVariable(lhs_symb_id)) try { lhs_symb_id = symbol_table.getOrigSymbIdForAuxVar(lhs_symb_id); @@ -3150,7 +3150,7 @@ DynamicModel::updateVarAndTrendModel() const int trend_var_symb_id = equations[eqn]->arg2->findTargetVariable(lhs_symb_id); if (trend_var_symb_id >= 0) { - if (symbol_table.isAuxiliaryVariable(trend_var_symb_id)) + if (symbol_table.isDiffAuxiliaryVariable(trend_var_symb_id)) try { trend_var_symb_id = symbol_table.getOrigSymbIdForAuxVar(trend_var_symb_id); @@ -3781,7 +3781,7 @@ DynamicModel::analyzePacEquationStructure(const string &name, map<string, string auto lhs = *lhss.begin(); int lhs_symb_id = lhs.first; int lhs_orig_symb_id = lhs_symb_id; - if (symbol_table.isAuxiliaryVariable(lhs_orig_symb_id)) + if (symbol_table.isDiffAuxiliaryVariable(lhs_orig_symb_id)) try { lhs_orig_symb_id = symbol_table.getOrigSymbIdForAuxVar(lhs_orig_symb_id); @@ -3949,14 +3949,8 @@ DynamicModel::computePacModelConsistentExpectationSubstitution(const string &nam auto create_target_lag = [&](int lag) { if (symbol_table.isAuxiliaryVariable(pac_target_symb_id)) - { - // We know it is a log, see ExprNode::matchParamTimesTargetMinusVariable() - /* We don’t use SymbolTable::getOrigSymbIdForAuxVar(), because it - does not work for unary ops, and changing this behaviour might - break stuff that relies on an exception in this case. */ - auto avi = symbol_table.getAuxVarInfo(pac_target_symb_id); - return AddLog(AddVariable(avi.get_orig_symb_id(), lag)); - } + // We know it is a log, see ExprNode::matchParamTimesTargetMinusVariable() + return AddLog(AddVariable(symbol_table.getOrigSymbIdForAuxVar(pac_target_symb_id), lag)); else return dynamic_cast<ExprNode *>(AddVariable(pac_target_symb_id, lag)); }; diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 77a9e38c..b7975f66 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -5210,7 +5210,7 @@ BinaryOpNode::findTargetVariableHelper1(int lhs_symb_id, int rhs_symb_id) const try { - if (datatree.symbol_table.isAuxiliaryVariable(rhs_symb_id) + if (datatree.symbol_table.isDiffAuxiliaryVariable(rhs_symb_id) && lhs_symb_id == datatree.symbol_table.getOrigSymbIdForAuxVar(rhs_symb_id)) return true; } diff --git a/src/SubModel.cc b/src/SubModel.cc index 3b36e99a..55e7d269 100644 --- a/src/SubModel.cc +++ b/src/SubModel.cc @@ -627,7 +627,7 @@ VarModelTable::setLhs(map<string, vector<int>> lhs_arg) { int lhs_last_orig_symb_id = ids; int lhs_orig_symb_id = ids; - if (symbol_table.isAuxiliaryVariable(lhs_orig_symb_id)) + if (symbol_table.isDiffAuxiliaryVariable(lhs_orig_symb_id)) try { lhs_last_orig_symb_id = lhs_orig_symb_id; diff --git a/src/SymbolTable.cc b/src/SymbolTable.cc index 72ee3307..62a5307f 100644 --- a/src/SymbolTable.cc +++ b/src/SymbolTable.cc @@ -712,12 +712,14 @@ SymbolTable::getOrigSymbIdForAuxVar(int aux_var_symb_id) const noexcept(false) || aux_var.get_type() == AuxVarType::exoLag || aux_var.get_type() == AuxVarType::diff || aux_var.get_type() == AuxVarType::diffLag - || aux_var.get_type() == AuxVarType::diffLead) + || aux_var.get_type() == AuxVarType::diffLead + || aux_var.get_type() == AuxVarType::diffForward + || aux_var.get_type() == AuxVarType::unaryOp) && aux_var.get_symb_id() == aux_var_symb_id) if (int r = aux_var.get_orig_symb_id(); r >= 0) return r; else - throw UnknownSymbolIDException(aux_var_symb_id); // Some diff var have orig_symb_id == -1 + throw UnknownSymbolIDException(aux_var_symb_id); // Some diff and unaryOp auxvars have orig_symb_id == -1 throw UnknownSymbolIDException(aux_var_symb_id); } diff --git a/src/SymbolTable.hh b/src/SymbolTable.hh index b9cf7287..f888eb2f 100644 --- a/src/SymbolTable.hh +++ b/src/SymbolTable.hh @@ -323,12 +323,10 @@ public: int searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const noexcept(false); /* Searches aux_vars for the aux var represented by aux_var_symb_id and returns its associated orig_symb_id. - Works only for endoLag, exoLag, diff, diffLag, diffLead. Throws an UnknownSymbolIDException if there is no orig_symb_id associated to - this aux var (either because it’s of the wrong type, or because there is - no such orig var for this specific aux var, e.g. a diff for a complex expression). - N.B.: some code might rely on the fact that, in particular, it does not work on unaryOp - type (to be verified) */ + this auxvar (either because it’s of the wrong type, or because there is + no such orig var for this specific auxvar, in case of complex expressions + in diff or unaryOp). */ int getOrigSymbIdForAuxVar(int aux_var_symb_id) const noexcept(false); /* Unrolls a chain of diffLag or diffLead aux vars until it founds a (regular) diff aux var. In other words: -- GitLab