diff --git a/src/ComputingTasks.cc b/src/ComputingTasks.cc
index 22b33b213ad9fe9e04f18ebdba841ebef9af3b7f..3ec9743bcd764984f363bdd173105e31b861ea0a 100644
--- a/src/ComputingTasks.cc
+++ b/src/ComputingTasks.cc
@@ -267,7 +267,7 @@ PerfectForesightWithExpectationErrorsSolverStatement::PerfectForesightWithExpect
 void
 PerfectForesightWithExpectationErrorsSolverStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
 {
-  mod_file_struct.perfect_foresight_solver_present = true;
+  mod_file_struct.perfect_foresight_with_expectation_errors_solver_present = true;
 }
 
 void
diff --git a/src/DynareBison.yy b/src/DynareBison.yy
index 687a85b9b998ea000f4a4b39d5318735e1b7b020..161b74b60bf2ddf58c0401e5db0bdcc489f98b12 100644
--- a/src/DynareBison.yy
+++ b/src/DynareBison.yy
@@ -186,7 +186,7 @@ class ParsingDriver;
 %token NO_IDENTIFICATION_MINIMAL NO_IDENTIFICATION_SPECTRUM NORMALIZE_JACOBIANS GRID_NBR
 %token TOL_RANK TOL_DERIV TOL_SV CHECKS_VIA_SUBSETS MAX_DIM_SUBSETS_GROUPS ZERO_MOMENTS_TOLERANCE
 %token MAX_NROWS SQUEEZE_SHOCK_DECOMPOSITION WITH_EPILOGUE MODEL_REMOVE MODEL_REPLACE MODEL_OPTIONS
-%token VAR_REMOVE ESTIMATED_PARAMS_REMOVE STATIC INCIDENCE RESID NON_ZERO
+%token VAR_REMOVE ESTIMATED_PARAMS_REMOVE STATIC INCIDENCE RESID NON_ZERO LEARNT_IN
 
 %token <vector<string>> SYMBOL_VEC
 
@@ -757,6 +757,8 @@ endval : ENDVAL ';' initval_list END ';'
          { driver.end_endval(false); }
        | ENDVAL '(' ALL_VALUES_REQUIRED ')' ';' initval_list END ';'
          { driver.end_endval(true); }
+       | ENDVAL '(' LEARNT_IN EQUAL INT_NUMBER ')' ';' initval_list END ';'
+         { driver.end_endval_learnt_in($5); }
        ;
 
 initval_list : initval_list initval_elem
@@ -1126,9 +1128,12 @@ tag_pair_list_for_selection : QUOTED_STRING
 shocks : SHOCKS ';' shock_list END ';' { driver.end_shocks(false); }
        | SHOCKS '(' OVERWRITE ')' ';' shock_list END ';' { driver.end_shocks(true); }
        | SHOCKS '(' OVERWRITE ')' ';'  END ';' { driver.end_shocks(true); }
-       | SHOCKS '(' SURPRISE ')' ';' surprise_shock_list END ';' { driver.end_shocks_surprise(false); }
-       | SHOCKS '(' SURPRISE COMMA OVERWRITE ')' ';' surprise_shock_list END ';' { driver.end_shocks_surprise(true); }
-       | SHOCKS '(' OVERWRITE COMMA SURPRISE ')' ';' surprise_shock_list END ';' { driver.end_shocks_surprise(true); }
+       | SHOCKS '(' SURPRISE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(false); }
+       | SHOCKS '(' SURPRISE COMMA OVERWRITE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(true); }
+       | SHOCKS '(' OVERWRITE COMMA SURPRISE ')' ';' det_shock_list END ';' { driver.end_shocks_surprise(true); }
+       | SHOCKS '(' LEARNT_IN EQUAL INT_NUMBER ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, false); }
+       | SHOCKS '(' LEARNT_IN EQUAL INT_NUMBER COMMA OVERWRITE ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($5, true); }
+       | SHOCKS '(' OVERWRITE COMMA LEARNT_IN EQUAL INT_NUMBER ')' ';' det_shock_list END ';' { driver.end_shocks_learnt_in($7, true); }
        ;
 
 shock_list : shock_list shock_elem
@@ -1150,9 +1155,9 @@ det_shock_elem : VAR symbol ';' PERIODS period_list ';' VALUES value_list ';'
                  { driver.add_det_shock($2, $5, $8, false); }
                ;
 
-surprise_shock_list : surprise_shock_list det_shock_elem
-                    | det_shock_elem
-                    ;
+det_shock_list : det_shock_list det_shock_elem
+               | det_shock_elem
+               ;
 
 heteroskedastic_shocks : HETEROSKEDASTIC_SHOCKS ';' heteroskedastic_shock_list END ';'
                          { driver.end_heteroskedastic_shocks(false); }
diff --git a/src/DynareFlex.ll b/src/DynareFlex.ll
index 8c9e15a651bc0662c663a32a3317f045c3cf8c02..40dc09bfd77c4730718f1b62d5351760bf77c3fb 100644
--- a/src/DynareFlex.ll
+++ b/src/DynareFlex.ll
@@ -888,6 +888,7 @@ DATE -?[0-9]+([ya]|m([1-9]|1[0-2])|q[1-4])
 <DYNARE_BLOCK>lag {return token::LAG;}
 <DYNARE_BLOCK>coeff {return token::COEFF;}
 <DYNARE_BLOCK>overwrite {return token::OVERWRITE;}
+<DYNARE_BLOCK>learnt_in {return token::LEARNT_IN;}
 <DYNARE_STATEMENT,DYNARE_BLOCK>upper_cholesky {return token::UPPER_CHOLESKY;}
 <DYNARE_STATEMENT,DYNARE_BLOCK>lower_cholesky {return token::LOWER_CHOLESKY;}
 <DYNARE_STATEMENT>chain {return token::CHAIN;}
diff --git a/src/ModFile.cc b/src/ModFile.cc
index c16a5ab22b007798bbdec72e70842b8a06b10d87..decf7921076ad6d7d6abc2460c53dd499647bbf5 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -148,6 +148,7 @@ ModFile::checkPass(bool nostrict, bool stochastic)
   if (dynamic_model.equation_number() == 0
       && (mod_file_struct.check_present
           || mod_file_struct.perfect_foresight_solver_present
+          || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present
           || stochastic_statement_present))
     {
       cerr << "ERROR: At least one model equation must be declared!" << endl;
@@ -184,9 +185,10 @@ ModFile::checkPass(bool nostrict, bool stochastic)
       exit(EXIT_FAILURE);
     }
 
-  if (mod_file_struct.perfect_foresight_solver_present && stochastic_statement_present)
+  if ((mod_file_struct.perfect_foresight_solver_present || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present)
+      && stochastic_statement_present)
     {
-      cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver,simul} and one of {stoch_simul, estimation, osr, ramsey_policy, discretionary_policy}. This is not possible: one cannot mix perfect foresight context with stochastic context in the same file." << endl;
+      cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver, simul, perfect_foresight_with_expectation_errors_solver} and one of {stoch_simul, estimation, osr, ramsey_policy, discretionary_policy}. This is not possible: one cannot mix perfect foresight context with stochastic context in the same file." << endl;
       exit(EXIT_FAILURE);
     }
 
@@ -308,6 +310,7 @@ ModFile::checkPass(bool nostrict, bool stochastic)
 
   if (linear
       && !mod_file_struct.perfect_foresight_solver_present
+      && !mod_file_struct.perfect_foresight_with_expectation_errors_solver_present
       && (dynamic_model.isUnaryOpUsedOnType(SymbolType::exogenous, UnaryOpcode::sign)
           || dynamic_model.isUnaryOpUsedOnType(SymbolType::exogenous, UnaryOpcode::abs)
           || dynamic_model.isBinaryOpUsedOnType(SymbolType::exogenous, BinaryOpcode::max)
@@ -576,9 +579,10 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool
       exit(EXIT_FAILURE);
     }
 
-  if (symbol_table.exo_det_nbr() > 0 && mod_file_struct.perfect_foresight_solver_present)
+  if (symbol_table.exo_det_nbr() > 0
+      && (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present))
     {
-      cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver, simul} and varexo_det declaration (all exogenous variables are deterministic in this case)" << endl;
+      cerr << "ERROR: A .mod file cannot contain both one of {perfect_foresight_solver, simul, perfect_foresight_with_expectation_errors_solver} and varexo_det declaration (all exogenous variables are deterministic in this case)" << endl;
       exit(EXIT_FAILURE);
     }
 
@@ -610,6 +614,18 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool
       exit(EXIT_FAILURE);
     }
 
+  if (mod_file_struct.shocks_learnt_in_present && !mod_file_struct.perfect_foresight_with_expectation_errors_solver_present)
+    {
+      cerr << "ERROR: the 'shocks(learnt_in=…)' block can only be used in conjunction with the 'perfect_foresight_with_expectation_errors_solver' command." << endl;
+      exit(EXIT_FAILURE);
+    }
+
+  if (mod_file_struct.endval_learnt_in_present && !mod_file_struct.perfect_foresight_with_expectation_errors_solver_present)
+    {
+      cerr << "ERROR: the 'endval(learnt_in=…)' block can only be used in conjunction with the 'perfect_foresight_with_expectation_errors_solver' command." << endl;
+      exit(EXIT_FAILURE);
+    }
+
   if (!mod_file_struct.ramsey_model_present)
     cout << "Found " << dynamic_model.equation_number() << " equation(s)." << endl;
   else
@@ -669,13 +685,16 @@ ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_o
           static_model.computingPass(derivsOrder, paramsDerivsOrder, global_eval_context, no_tmp_terms, block, bytecode);
         }
       // Set things to compute for dynamic model
-      if (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.check_present
+      if (mod_file_struct.perfect_foresight_solver_present
+          || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present
+          || mod_file_struct.check_present
           || mod_file_struct.stoch_simul_present
           || mod_file_struct.estimation_present || mod_file_struct.osr_present
           || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present
           || mod_file_struct.calib_smoother_present || mod_file_struct.mom_estimation_present)
         {
-          if (mod_file_struct.perfect_foresight_solver_present)
+          if (mod_file_struct.perfect_foresight_solver_present
+              || mod_file_struct.perfect_foresight_with_expectation_errors_solver_present)
             {
               int derivsOrder = 1;
               if (output == OutputType::second)
@@ -897,9 +916,11 @@ ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global,
   // May be later modified by a shocks block
   mOutputFile << "M_.sigma_e_is_diagonal = true;" << endl;
 
-  // Initialize M_.det_shocks, M_.surprise_shocks and M_.heteroskedastic_shocks
+  // Initialize M_.det_shocks, M_.surprise_shocks, M_.learnt_shocks, M_.learnt_endval and M_.heteroskedastic_shocks
   mOutputFile << "M_.det_shocks = [];" << endl
               << "M_.surprise_shocks = [];" << endl
+              << "M_.learnt_shocks = [];" << endl
+              << "M_.learnt_endval = [];" << endl
               << "M_.heteroskedastic_shocks.Qvalue_orig = [];" << endl
               << "M_.heteroskedastic_shocks.Qscale_orig = [];" << endl;
 
diff --git a/src/NumericalInitialization.cc b/src/NumericalInitialization.cc
index 27849afb5361c3be77dcb42c0b682991f3671e66..afe6667ab35db81c0e1fe483e2e8682dad4aea8c 100644
--- a/src/NumericalInitialization.cc
+++ b/src/NumericalInitialization.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2003-2021 Dynare Team
+ * Copyright © 2003-2022 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -299,6 +299,54 @@ EndValStatement::writeJsonOutput(ostream &output) const
   output << "]}";
 }
 
+EndValLearntInStatement::EndValLearntInStatement(int learnt_in_period_arg,
+                                                 const InitOrEndValStatement::init_values_t &init_values_arg,
+                                                 const SymbolTable &symbol_table_arg) :
+  learnt_in_period{learnt_in_period_arg},
+  init_values{move(init_values_arg)},
+  symbol_table{symbol_table_arg}
+{
+}
+
+void
+EndValLearntInStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
+{
+  mod_file_struct.endval_learnt_in_present = true;
+}
+
+void
+EndValLearntInStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  output << "M_.learnt_endval = [ M_.learnt_endval;" << endl;
+  for (auto [symb_id, value] : init_values)
+    {
+      output << "struct('learnt_in'," << learnt_in_period
+             << ",'exo_id'," << symbol_table.getTypeSpecificID(symb_id)+1
+             << ",'value',";
+      value->writeOutput(output);
+      output << ");" << endl;
+    }
+  output << "];" << endl;
+}
+
+void
+EndValLearntInStatement::writeJsonOutput(ostream &output) const
+{
+  output << R"({"statementName": "endval", "learnt_in": )"
+         << learnt_in_period <<  R"(, "vals": [)";
+  for (auto it = init_values.begin();
+       it != init_values.end(); ++it)
+    {
+      auto [symb_id, value] = *it;
+      if (it != init_values.begin())
+        output << ", ";
+      output << R"({"name": ")" << symbol_table.getName(symb_id) << R"(", )" << R"("value": ")";
+      value->writeJsonOutput(output, {}, {});
+      output << R"("})";
+    }
+  output << "]}";
+}
+
 HistValStatement::HistValStatement(hist_values_t hist_values_arg,
                                    const SymbolTable &symbol_table_arg,
                                    bool all_values_required_arg) :
diff --git a/src/NumericalInitialization.hh b/src/NumericalInitialization.hh
index 2c58656cccc5617dd0d6145b867f1f75cc03295a..5c5fd611fc7a5a5981e35cd7b85202a79d9e70e9 100644
--- a/src/NumericalInitialization.hh
+++ b/src/NumericalInitialization.hh
@@ -96,6 +96,20 @@ public:
   void writeJsonOutput(ostream &output) const override;
 };
 
+class EndValLearntInStatement : public Statement
+{
+public:
+  const int learnt_in_period;
+  const InitOrEndValStatement::init_values_t init_values;
+  const SymbolTable &symbol_table;
+  EndValLearntInStatement(int learnt_in_period_arg,
+                          const InitOrEndValStatement::init_values_t &init_values_arg,
+                          const SymbolTable &symbol_table_arg);
+  void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
+  void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
+  void writeJsonOutput(ostream &output) const override;
+};
+
 class HistValStatement : public Statement
 {
 public:
diff --git a/src/ParsingDriver.cc b/src/ParsingDriver.cc
index 48ba4537a5ae25a11cb9621f780ffe0014e1715e..60f70d7fcbc0c7596162fae36fb13f49c8ea395c 100644
--- a/src/ParsingDriver.cc
+++ b/src/ParsingDriver.cc
@@ -747,6 +747,16 @@ ParsingDriver::end_endval(bool all_values_required)
   init_values.clear();
 }
 
+void
+ParsingDriver::end_endval_learnt_in(const string &learnt_in_period)
+{
+  for (auto [symb_id, value] : init_values)
+    if (mod_file->symbol_table.getType(symb_id) != SymbolType::exogenous)
+      error("endval(learnt_in=...): " + mod_file->symbol_table.getName(symb_id) + " is not an exogenous variable");
+  mod_file->addStatement(make_unique<EndValLearntInStatement>(stoi(learnt_in_period), init_values, mod_file->symbol_table));
+  init_values.clear();
+}
+
 void
 ParsingDriver::end_histval(bool all_values_required)
 {
@@ -848,6 +858,18 @@ ParsingDriver::end_shocks_surprise(bool overwrite)
   det_shocks.clear();
 }
 
+void
+ParsingDriver::end_shocks_learnt_in(const string &learnt_in_period, bool overwrite)
+{
+  int learnt_in_period_int = stoi(learnt_in_period);
+  for (auto &[symb_id, vals] : det_shocks)
+    for (auto [period1, period2, expr] : vals)
+      if (period1 < learnt_in_period_int)
+        error("shocks: for variable " + mod_file->symbol_table.getName(symb_id) + ", shock period (" + to_string(period1) + ") is earlier than the period in which the shock is learnt (" + learnt_in_period + ")");
+  mod_file->addStatement(make_unique<ShocksLearntInStatement>(learnt_in_period_int, overwrite, det_shocks, mod_file->symbol_table));
+  det_shocks.clear();
+}
+
 void
 ParsingDriver::end_heteroskedastic_shocks(bool overwrite)
 {
diff --git a/src/ParsingDriver.hh b/src/ParsingDriver.hh
index a421bc5ea21bf88b92d9c587b5a20cfb11acea69..2329a2e999a40708c271f35f55c47fa3a7010b03 100644
--- a/src/ParsingDriver.hh
+++ b/src/ParsingDriver.hh
@@ -101,7 +101,7 @@ private:
   //! Checks that a given symbol exists and is a endogenous, and stops with an error message if it isn't
   void check_symbol_is_endogenous(const string &name);
 
-  //! Checks that a given symbol exists and is a exogenous, and stops with an error message if it isn't
+  //! Checks that a given symbol exists and is a exogenous (possibly deterministic), and stops with an error message if it isn't
   void check_symbol_is_exogenous(const string &name);
 
   //! Checks for symbol existence in model block. If it doesn't exist, an error message is stored to be printed at
@@ -423,6 +423,8 @@ public:
   void end_initval(bool all_values_required);
   //! Writes end of an endval block
   void end_endval(bool all_values_required);
+  //! Writes end of an endval(learnt_in=…) block
+  void end_endval_learnt_in(const string &learnt_in_period);
   //! Writes end of an histval block
   void end_histval(bool all_values_required);
   //! Writes end of an homotopy_setup block
@@ -447,6 +449,8 @@ public:
   void end_mshocks(bool overwrite);
   //! Writes a shocks(surprise) statement
   void end_shocks_surprise(bool overwrite);
+  //! Writes a shocks(learnt_in=…) block
+  void end_shocks_learnt_in(const string &learnt_in_period, bool overwrite);
   //! Writes a heteroskedastic_shocks statement
   void end_heteroskedastic_shocks(bool overwrite);
   /* Adds a deterministic shock, a path element inside a
diff --git a/src/Shocks.cc b/src/Shocks.cc
index 0e77c0c9d8dd9fb628110a6c17e485f87fdb24e0..9031774278a8192c6030e789a6a321536477f5c5 100644
--- a/src/Shocks.cc
+++ b/src/Shocks.cc
@@ -491,6 +491,73 @@ ShocksSurpriseStatement::writeJsonOutput(ostream &output) const
   output << "]}";
 }
 
+ShocksLearntInStatement::ShocksLearntInStatement(int learnt_in_period_arg, bool overwrite_arg,
+                                                 AbstractShocksStatement::det_shocks_t learnt_shocks_arg,
+                                                 const SymbolTable &symbol_table_arg) :
+  learnt_in_period{learnt_in_period_arg}, overwrite{overwrite_arg},
+  learnt_shocks{move(learnt_shocks_arg)}, symbol_table{symbol_table_arg}
+{
+}
+
+void
+ShocksLearntInStatement::checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings)
+{
+  mod_file_struct.shocks_learnt_in_present = true;
+}
+
+void
+ShocksLearntInStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
+{
+  if (overwrite)
+    output << "if ~isempty(M_.learnt_shocks)" << endl
+           << "  M_.learnt_shocks = M_.learnt_shocks([M_.learnt_shocks.learnt_in] ~= " << learnt_in_period << ");" << endl
+           << "end" << endl;
+
+  output << "M_.learnt_shocks = [ M_.learnt_shocks;" << endl;
+  for (const auto &[id, shock_vec] : learnt_shocks)
+    {
+      for (const auto &[period1, period2, value] : shock_vec)
+        {
+          output << "struct('learnt_in'," << learnt_in_period
+                 << ",'exo_id'," << symbol_table.getTypeSpecificID(id)+1
+                 << ",'periods'," << period1 << ":" << period2
+                 << ",'value',";
+          value->writeOutput(output);
+          output << ");" << endl;
+        }
+    }
+  output << "];" << endl;
+}
+
+void
+ShocksLearntInStatement::writeJsonOutput(ostream &output) const
+{
+  output << R"({"statementName": "shocks")"
+         << R"(, "learnt_in": )" << learnt_in_period
+         << R"(, "overwrite": )" << (overwrite ? "true" : "false")
+         << R"(, "learnt_shocks": [)";
+  for (auto it = learnt_shocks.begin(); it != learnt_shocks.end(); ++it)
+    {
+      if (it != learnt_shocks.begin())
+        output << ", ";
+      output << R"({"var": ")" << symbol_table.getName(it->first) << R"(", )"
+             << R"("values": [)";
+      for (auto it1 = it->second.begin(); it1 != it->second.end(); ++it1)
+        {
+          auto [period1, period2, value] = *it1;
+          if (it1 != it->second.begin())
+            output << ", ";
+          output << R"({"period1": )" << period1 << ", "
+                 << R"("period2": )" << period2 << ", "
+                 << R"("value": ")";
+          value->writeJsonOutput(output, {}, {});
+          output << R"("})";
+        }
+      output << "]}";
+    }
+  output << "]}";
+}
+
 ConditionalForecastPathsStatement::ConditionalForecastPathsStatement(AbstractShocksStatement::det_shocks_t paths_arg,
                                                                      const SymbolTable &symbol_table_arg) :
   paths{move(paths_arg)},
diff --git a/src/Shocks.hh b/src/Shocks.hh
index 83ec46e93ec190fce16d35e6467b3e367bc44bc1..dac2ab0c224c8160f2a61470309980ad81321dd0 100644
--- a/src/Shocks.hh
+++ b/src/Shocks.hh
@@ -106,6 +106,27 @@ public:
   void writeJsonOutput(ostream &output) const override;
 };
 
+/* Represents a shocks(learnt_in=…) block.
+   Given the differences with the plain “shocks” block, it was easier to make
+   it a separate class. */
+class ShocksLearntInStatement : public Statement
+{
+public:
+  const int learnt_in_period;
+  //! Does this "shocks(learnt_in=…)" statement replace the previous ones?
+  const bool overwrite;
+  const AbstractShocksStatement::det_shocks_t learnt_shocks;
+private:
+  const SymbolTable &symbol_table;
+public:
+  ShocksLearntInStatement(int learnt_in_period_arg, bool overwrite_arg,
+                          AbstractShocksStatement::det_shocks_t learnt_shocks_arg,
+                          const SymbolTable &symbol_table_arg);
+  void checkPass(ModFileStructure &mod_file_struct, WarningConsolidation &warnings) override;
+  void writeOutput(ostream &output, const string &basename, bool minimal_workspace) const override;
+  void writeJsonOutput(ostream &output) const override;
+};
+
 class ConditionalForecastPathsStatement : public Statement
 {
 private:
diff --git a/src/Statement.hh b/src/Statement.hh
index 57d36061f6153798820a5e0095a71195d26230cb..58e3e9d5a3af7b00f01731803e6f411a784e0357 100644
--- a/src/Statement.hh
+++ b/src/Statement.hh
@@ -36,8 +36,10 @@ public:
   bool check_present{false};
   //! Whether steady is present
   bool steady_present{false};
-  //! Whether a perfect_foresight_solver/simul/perfect_foresight_with_expectation_errors_solver statement is present
+  //! Whether a perfect_foresight_solver/simul statement is present
   bool perfect_foresight_solver_present{false};
+  //! Whether a perfect_foresight_with_expectation_errors_solver statement is present
+  bool perfect_foresight_with_expectation_errors_solver_present{false};
   //! Whether a stoch_simul statement is present
   bool stoch_simul_present{false};
   //! Whether an estimation statement is present
@@ -147,6 +149,10 @@ public:
   set<int> parameters_in_planner_discount;
   // Whether a shocks(surprise) block appears
   bool shocks_surprise_present{false};
+  // Whether a shocks(learnt_in=…) block appears
+  bool shocks_learnt_in_present{false};
+  // Whether an endval(learnt_in=…) block appears
+  bool endval_learnt_in_present{false};
   // Whether an occbin_constraints block appears
   bool occbin_constraints_present{false};
   // Whether a ramsey_constraints block appears