From 90b1235a64ab37cb26459ba70801fa1776c12495 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Tue, 20 Jul 2021 12:10:58 +0200
Subject: [PATCH] New utility to check if an expression contains an exogenous
 (possibly deterministic)

---
 src/ExprNode.cc      | 9 +++++++++
 src/ExprNode.hh      | 3 +++
 src/ParsingDriver.cc | 7 +------
 src/StaticModel.cc   | 9 ++-------
 4 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/ExprNode.cc b/src/ExprNode.cc
index b1f77541..a8194d86 100644
--- a/src/ExprNode.cc
+++ b/src/ExprNode.cc
@@ -389,6 +389,15 @@ ExprNode::isConstant() const
   return symbs_lags.empty();
 }
 
+bool
+ExprNode::hasExogenous() const
+{
+  set<pair<int, int>> symbs_lags;
+  collectDynamicVariables(SymbolType::exogenous, symbs_lags);
+  collectDynamicVariables(SymbolType::exogenousDet, symbs_lags);
+  return !symbs_lags.empty();
+}
+
 
 NumConstNode::NumConstNode(DataTree &datatree_arg, int idx_arg, int id_arg) :
   ExprNode{datatree_arg, idx_arg},
diff --git a/src/ExprNode.hh b/src/ExprNode.hh
index 766f00cf..85d4ce79 100644
--- a/src/ExprNode.hh
+++ b/src/ExprNode.hh
@@ -707,6 +707,9 @@ public:
   /* Returns true if the expression contains no endogenous, no exogenous and no
      exogenous deterministic */
   bool isConstant() const;
+
+  // Returns true if the expression contains an exogenous or an exogenous deterministic
+  bool hasExogenous() const;
 };
 
 //! Object used to compare two nodes (using their indexes)
diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc
index 60d05907..1059e81c 100644
--- a/src/ParsingDriver.cc
+++ b/src/ParsingDriver.cc
@@ -2796,13 +2796,8 @@ expr_t
 ParsingDriver::add_steady_state(expr_t arg1)
 {
   // Forbid exogenous variables, see dynare#825
-  set<int> r;
-  arg1->collectVariables(SymbolType::exogenous, r);
-  if (r.size() > 0)
+  if (arg1->hasExogenous())
     error("Exogenous variables are not allowed in the context of the STEADY_STATE() operator.");
-  arg1->collectVariables(SymbolType::exogenousDet, r);
-  if (r.size() > 0)
-    error("Exogenous deterministic variables are not allowed in the context of the STEADY_STATE() operator.");
 
   return data_tree->AddSteadyState(arg1);
 }
diff --git a/src/StaticModel.cc b/src/StaticModel.cc
index e8cccd15..daf54426 100644
--- a/src/StaticModel.cc
+++ b/src/StaticModel.cc
@@ -1829,13 +1829,8 @@ bool
 StaticModel::exoPresentInEqs() const
 {
   for (auto equation : equations)
-    {
-      set<int> result;
-      equation->collectVariables(SymbolType::exogenous, result);
-      equation->collectVariables(SymbolType::exogenousDet, result);
-      if (!result.empty())
-        return true;
-    }
+    if (equation->hasExogenous())
+      return true;
   return false;
 }
 
-- 
GitLab