diff --git a/src/DynamicModel.cc b/src/DynamicModel.cc index 29e8bd3fdf5247a0d21ff8c52218cc1b0e28c902..269d09037a816ef95e192dd6a95709737cb5c1c5 100644 --- a/src/DynamicModel.cc +++ b/src/DynamicModel.cc @@ -172,7 +172,7 @@ DynamicModel::writeBytecodeDerivative(BytecodeWriter &code_file, int eq, int sym { if (auto it = derivatives[1].find({ eq, getDerivID(symbol_table.getID(SymbolType::endogenous, symb_id), lag) }); it != derivatives[1].end()) - it->second->writeBytecodeOutput(code_file, false, temporary_terms, temporary_terms_idxs, true, false, tef_terms); + it->second->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms, temporary_terms_idxs, tef_terms); else code_file << FLDZ_{}; } @@ -182,7 +182,7 @@ DynamicModel::writeBytecodeChainRuleDerivative(BytecodeWriter &code_file, int bl { if (auto it = blocks_derivatives[blk].find({ eq, var, lag }); it != blocks_derivatives[blk].end()) - it->second->writeBytecodeOutput(code_file, false, temporary_terms, temporary_terms_idxs, true, false, tef_terms); + it->second->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms, temporary_terms_idxs, tef_terms); else code_file << FLDZ_{}; } @@ -871,9 +871,9 @@ DynamicModel::writeDynamicBytecode(const string &basename) const temporary_terms_t temporary_terms_union; deriv_node_temp_terms_t tef_terms; - writeBytecodeTemporaryTerms(code_file, true, false, temporary_terms_union, temporary_terms_idxs, tef_terms); + writeBytecodeTemporaryTerms(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, temporary_terms_idxs, tef_terms); - writeBytecodeModelEquations(code_file, true, false, temporary_terms_union, temporary_terms_idxs, tef_terms); + writeBytecodeModelEquations(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FENDEQU_{}; @@ -896,7 +896,7 @@ DynamicModel::writeDynamicBytecode(const string &basename) const if (!my_derivatives[eq].size()) my_derivatives[eq].clear(); my_derivatives[eq].emplace_back(var, lag, count_u); - d1->writeBytecodeOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, true, false, tef_terms); + d1->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FSTPU_{count_u}; count_u++; @@ -941,7 +941,7 @@ DynamicModel::writeDynamicBytecode(const string &basename) const prev_lag = lag; count_col_endo++; } - d1->writeBytecodeOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, true, false, tef_terms); + d1->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FSTPG3_{eq, var, lag, count_col_endo-1}; } prev_var = -1; @@ -958,7 +958,7 @@ DynamicModel::writeDynamicBytecode(const string &basename) const prev_lag = lag; count_col_exo++; } - d1->writeBytecodeOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, true, false, tef_terms); + d1->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FSTPG3_{eq, var, lag, count_col_exo-1}; } // Update jump offset for previous JMP @@ -1053,10 +1053,10 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const for (auto it : blocks_temporary_terms[block][eq]) { if (dynamic_cast<AbstractExternalFunctionNode *>(it)) - it->writeBytecodeExternalFunctionOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); + it->writeBytecodeExternalFunctionOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FNUMEXPR_{ExpressionType::TemporaryTerm, blocks_temporary_terms_idxs.at(it)}; - it->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); + it->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FSTPT_{blocks_temporary_terms_idxs.at(it)}; temporary_terms_union.insert(it); } @@ -1082,16 +1082,16 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const eq_node = getBlockEquationExpr(block, i); lhs = eq_node->arg1; rhs = eq_node->arg2; - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); - lhs->writeBytecodeOutput(code_file, true, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); + rhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + lhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicAssignmentLHS, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); } else if (equ_type == EquationType::evaluateRenormalized) { eq_node = getBlockEquationRenormalizedExpr(block, i); lhs = eq_node->arg1; rhs = eq_node->arg2; - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); - lhs->writeBytecodeOutput(code_file, true, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); + rhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + lhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicAssignmentLHS, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); } break; case BlockSimulationType::solveBackwardComplete: @@ -1111,8 +1111,8 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const eq_node = getBlockEquationExpr(block, i); lhs = eq_node->arg1; rhs = eq_node->arg2; - lhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); + lhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + rhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FBINARY_{BinaryOpcode::minus} << FSTPR_{i - block_recursive}; } @@ -1239,7 +1239,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const int eq = getBlockEquationID(block, eqr); int varr = 0; // Dummy value, actually unused by the bytecode MEX code_file << FNUMEXPR_{ExpressionType::FirstExoDerivative, eqr, varr, lag}; - d->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); + d->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FSTPG3_{eq, var, lag, blocks_jacob_cols_exo[block].at({ var, lag })}; } for (const auto &[indices, d] : blocks_derivatives_exo_det[block]) @@ -1248,7 +1248,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const int eq = getBlockEquationID(block, eqr); int varr = 0; // Dummy value, actually unused by the bytecode MEX code_file << FNUMEXPR_{ExpressionType::FirstExodetDerivative, eqr, varr, lag}; - d->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); + d->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FSTPG3_{eq, var, lag, blocks_jacob_cols_exo_det[block].at({ var, lag })}; } for (const auto &[indices, d] : blocks_derivatives_other_endo[block]) @@ -1257,7 +1257,7 @@ DynamicModel::writeDynamicBlockBytecode(const string &basename) const int eq = getBlockEquationID(block, eqr); int varr = 0; // Dummy value, actually unused by the bytecode MEX code_file << FNUMEXPR_{ExpressionType::FirstOtherEndoDerivative, eqr, varr, lag}; - d->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, true, false, tef_terms); + d->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::dynamicModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FSTPG3_{eq, var, lag, blocks_jacob_cols_other_endo[block].at({ var, lag })}; } diff --git a/src/ExprNode.cc b/src/ExprNode.cc index c2f3f8e4794a02e2eceb2dce0bff38cb72430515..4a0db3d2ee1410392448b004f3a47fb6e41a6e6e 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -118,9 +118,9 @@ ExprNode::checkIfTemporaryTermThenWrite(ostream &output, ExprNodeOutputType outp bool ExprNode::checkIfTemporaryTermThenWriteBytecode(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - bool dynamic, bool steady_dynamic) const + const temporary_terms_idxs_t &temporary_terms_idxs) const { if (!temporary_terms.contains(const_cast<ExprNode *>(this))) return false; @@ -129,16 +129,24 @@ ExprNode::checkIfTemporaryTermThenWriteBytecode(BytecodeWriter &code_file, // It is the responsibility of the caller to ensure that all temporary terms have their index assert(it2 != temporary_terms_idxs.end()); - /* If we are inside a steady_state() operator, the temporary terms do not - apply, since those refer to the dynamic model (assuming that writeBytecodeOutput() - was initially not called with steady_dynamic=true). */ - if (steady_dynamic) - return false; - - if (dynamic) - code_file << FLDT_{it2->second}; - else - code_file << FLDST_{it2->second}; + switch (output_type) + { + case ExprNodeBytecodeOutputType::dynamicSteadyStateOperator: + /* If we are inside a steady_state() operator, the temporary terms do not + apply, since those refer to the dynamic model (assuming that writeBytecodeOutput() + was initially not called with steady_dynamic=true). */ + return false; + case ExprNodeBytecodeOutputType::dynamicModel: + code_file << FLDT_{it2->second}; + break; + case ExprNodeBytecodeOutputType::staticModel: + code_file << FLDST_{it2->second}; + break; + case ExprNodeBytecodeOutputType::dynamicAssignmentLHS: + case ExprNodeBytecodeOutputType::staticAssignmentLHS: + cerr << "ExprNode::checkIfTemporaryTermThenWriteBytecode: can't assign a temporary term" << endl; + exit(EXIT_FAILURE); + } return true; } @@ -229,11 +237,9 @@ ExprNode::writeJsonExternalFunctionOutput([[maybe_unused]] vector<string> &efout void ExprNode::writeBytecodeExternalFunctionOutput([[maybe_unused]] BytecodeWriter &code_file, - [[maybe_unused]] bool assignment_lhs, + [[maybe_unused]] ExprNodeBytecodeOutputType output_type, [[maybe_unused]] const temporary_terms_t &temporary_terms, [[maybe_unused]] const temporary_terms_idxs_t &temporary_terms_idxs, - [[maybe_unused]] bool dynamic, - [[maybe_unused]] bool steady_dynamic, [[maybe_unused]] deriv_node_temp_terms_t &tef_terms) const { // Nothing to do @@ -504,13 +510,13 @@ NumConstNode::eval([[maybe_unused]] const eval_context_t &eval_context) const no } void -NumConstNode::writeBytecodeOutput(BytecodeWriter &code_file, [[maybe_unused]] bool assignment_lhs, +NumConstNode::writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, - [[maybe_unused]] bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms) const { - if (!checkIfTemporaryTermThenWriteBytecode(code_file, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic)) + assert(!isAssignmentLHSBytecodeOutput(output_type)); + if (!checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) code_file << FLDC_{datatree.num_constants.getDouble(id)}; } @@ -1298,56 +1304,43 @@ VariableNode::eval(const eval_context_t &eval_context) const noexcept(false) } void -VariableNode::writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, +VariableNode::writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const { - if (checkIfTemporaryTermThenWriteBytecode(code_file, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) return; auto type = get_type(); if (type == SymbolType::modelLocalVariable || type == SymbolType::modFileLocalVariable) - datatree.getLocalVariable(symb_id)->writeBytecodeOutput(code_file, assignment_lhs, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + datatree.getLocalVariable(symb_id)->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); else { int tsid = datatree.symbol_table.getTypeSpecificID(symb_id); - if (!assignment_lhs) + switch (output_type) { - if (dynamic) - { - if (steady_dynamic) // steady state values in a dynamic model - code_file << FLDVS_{type, tsid}; - else - { - if (type == SymbolType::parameter) - code_file << FLDV_{type, tsid}; - else - code_file << FLDV_{type, tsid, lag}; - } - } + case ExprNodeBytecodeOutputType::dynamicModel: + if (type == SymbolType::parameter) + code_file << FLDV_{type, tsid}; else - code_file << FLDSV_{type, tsid}; - } - else - { - if (dynamic) - { - if (steady_dynamic) // steady state values in a dynamic model - { - cerr << "Impossible case: steady_state operator in LHS of an assignment equation" << endl; - exit(EXIT_FAILURE); - } - else - { - if (type == SymbolType::parameter) - code_file << FSTPV_{type, tsid}; - else - code_file << FSTPV_{type, tsid, lag}; - } - } + code_file << FLDV_{type, tsid, lag}; + break; + case ExprNodeBytecodeOutputType::staticModel: + code_file << FLDSV_{type, tsid}; + break; + case ExprNodeBytecodeOutputType::dynamicSteadyStateOperator: + code_file << FLDVS_{type, tsid}; + break; + case ExprNodeBytecodeOutputType::dynamicAssignmentLHS: + if (type == SymbolType::parameter) + code_file << FSTPV_{type, tsid}; else - code_file << FSTPSV_{type, tsid}; + code_file << FSTPV_{type, tsid, lag}; + break; + case ExprNodeBytecodeOutputType::staticAssignmentLHS: + code_file << FSTPSV_{type, tsid}; + break; } } } @@ -2978,13 +2971,14 @@ UnaryOpNode::writeJsonExternalFunctionOutput(vector<string> &efout, } void -UnaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, bool assignment_lhs, +UnaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const { - arg->writeBytecodeExternalFunctionOutput(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + arg->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); } double @@ -3066,19 +3060,36 @@ UnaryOpNode::eval(const eval_context_t &eval_context) const noexcept(false) } void -UnaryOpNode::writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, +UnaryOpNode::writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const { - if (checkIfTemporaryTermThenWriteBytecode(code_file, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic)) + assert(!isAssignmentLHSBytecodeOutput(output_type)); + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) return; if (op_code == UnaryOpcode::steadyState) - arg->writeBytecodeOutput(code_file, assignment_lhs, temporary_terms, temporary_terms_idxs, dynamic, true, tef_terms); + { + ExprNodeBytecodeOutputType new_output_type{output_type}; + switch (output_type) + { + case ExprNodeBytecodeOutputType::dynamicModel: + new_output_type = ExprNodeBytecodeOutputType::dynamicSteadyStateOperator; + break; + case ExprNodeBytecodeOutputType::staticModel: + case ExprNodeBytecodeOutputType::dynamicSteadyStateOperator: + break; + case ExprNodeBytecodeOutputType::dynamicAssignmentLHS: + case ExprNodeBytecodeOutputType::staticAssignmentLHS: + cerr << "UnaryOpNode::writeBytecodeOutput: impossible case" << endl; + exit(EXIT_FAILURE); + } + arg->writeBytecodeOutput(code_file, new_output_type, temporary_terms, temporary_terms_idxs, tef_terms); + } else { - arg->writeBytecodeOutput(code_file, assignment_lhs, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + arg->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); code_file << FUNARY_{op_code}; } } @@ -4315,18 +4326,19 @@ BinaryOpNode::eval(const eval_context_t &eval_context) const noexcept(false) } void -BinaryOpNode::writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, +BinaryOpNode::writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const { - if (checkIfTemporaryTermThenWriteBytecode(code_file, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic)) + assert(!isAssignmentLHSBytecodeOutput(output_type)); + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) return; if (op_code == BinaryOpcode::powerDeriv) code_file << FLDC_{static_cast<double>(powerDerivOrder)}; - arg1->writeBytecodeOutput(code_file, assignment_lhs, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); - arg2->writeBytecodeOutput(code_file, assignment_lhs, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + arg1->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + arg2->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); code_file << FBINARY_{op_code}; } @@ -4765,15 +4777,16 @@ BinaryOpNode::writeJsonExternalFunctionOutput(vector<string> &efout, } void -BinaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, bool assignment_lhs, +BinaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const { - arg1->writeBytecodeExternalFunctionOutput(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); - arg2->writeBytecodeExternalFunctionOutput(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + arg1->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); + arg2->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); } int @@ -6001,17 +6014,18 @@ TrinaryOpNode::eval(const eval_context_t &eval_context) const noexcept(false) } void -TrinaryOpNode::writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, +TrinaryOpNode::writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const { - if (checkIfTemporaryTermThenWriteBytecode(code_file, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic)) + assert(!isAssignmentLHSBytecodeOutput(output_type)); + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) return; - arg1->writeBytecodeOutput(code_file, assignment_lhs, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); - arg2->writeBytecodeOutput(code_file, assignment_lhs, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); - arg3->writeBytecodeOutput(code_file, assignment_lhs, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + arg1->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + arg2->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); + arg3->writeBytecodeOutput(code_file, output_type, temporary_terms, temporary_terms_idxs, tef_terms); code_file << FTRINARY_{op_code}; } @@ -6190,17 +6204,18 @@ TrinaryOpNode::writeJsonExternalFunctionOutput(vector<string> &efout, } void -TrinaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, bool assignment_lhs, +TrinaryOpNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const { - arg1->writeBytecodeExternalFunctionOutput(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); - arg2->writeBytecodeExternalFunctionOutput(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); - arg3->writeBytecodeExternalFunctionOutput(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + arg1->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); + arg2->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); + arg3->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); } void @@ -6674,14 +6689,15 @@ AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map<int } int -AbstractExternalFunctionNode::writeBytecodeExternalFunctionArguments(BytecodeWriter &code_file, bool assignment_lhs, +AbstractExternalFunctionNode::writeBytecodeExternalFunctionArguments(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const { for (auto argument : arguments) - argument->writeBytecodeOutput(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + argument->writeBytecodeOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); return static_cast<int>(arguments.size()); } @@ -7228,39 +7244,40 @@ ExternalFunctionNode::composeDerivatives(const vector<expr_t> &dargs) } void -ExternalFunctionNode::writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, +ExternalFunctionNode::writeBytecodeOutput(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, - [[maybe_unused]] bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const { - if (steady_dynamic) + if (output_type == ExprNodeBytecodeOutputType::dynamicSteadyStateOperator) { cerr << "ERROR: The expression inside a steady_state operator cannot contain external functions" << endl; exit(EXIT_FAILURE); } - if (checkIfTemporaryTermThenWriteBytecode(code_file, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) return; - if (!assignment_lhs) + if (!isAssignmentLHSBytecodeOutput(output_type)) code_file << FLDTEF_{getIndxInTefTerms(symb_id, tef_terms)}; else code_file << FSTPTEF_{getIndxInTefTerms(symb_id, tef_terms)}; } void -ExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, bool assignment_lhs, +ExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const { int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); for (auto argument : arguments) - argument->writeBytecodeExternalFunctionOutput(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + argument->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) { @@ -7277,8 +7294,8 @@ ExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_f nb_output_arguments = 2; else nb_output_arguments = 1; - int nb_input_arguments{writeBytecodeExternalFunctionArguments(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms)}; + int nb_input_arguments{writeBytecodeExternalFunctionArguments(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms)}; FCALL_ fcall{nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx}; switch (nb_output_arguments) @@ -7619,25 +7636,25 @@ FirstDerivExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType } void -FirstDerivExternalFunctionNode::writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, +FirstDerivExternalFunctionNode::writeBytecodeOutput(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, - [[maybe_unused]] bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const { - if (steady_dynamic) + if (output_type == ExprNodeBytecodeOutputType::dynamicSteadyStateOperator) { cerr << "ERROR: The expression inside a steady_state operator cannot contain external functions" << endl; exit(EXIT_FAILURE); } - if (checkIfTemporaryTermThenWriteBytecode(code_file, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) return; int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); assert(first_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); - if (!assignment_lhs) + if (!isAssignmentLHSBytecodeOutput(output_type)) code_file << FLDTEFD_{getIndxInTefTerms(symb_id, tef_terms), inputIndex}; else code_file << FSTPTEFD_{getIndxInTefTerms(symb_id, tef_terms), inputIndex}; @@ -7769,9 +7786,10 @@ FirstDerivExternalFunctionNode::writeJsonExternalFunctionOutput(vector<string> & } void -FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, bool assignment_lhs, +FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const { int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); @@ -7782,17 +7800,16 @@ FirstDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWrit if (first_deriv_symb_id == symb_id) { expr_t parent = datatree.AddExternalFunction(symb_id, arguments); - parent->writeBytecodeExternalFunctionOutput(code_file, assignment_lhs, - temporary_terms, temporary_terms_idxs, - dynamic, steady_dynamic, tef_terms); + parent->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); return; } if (alreadyWrittenAsTefTerm(first_deriv_symb_id, tef_terms)) return; - int nb_add_input_arguments{writeBytecodeExternalFunctionArguments(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms)}; + int nb_add_input_arguments{writeBytecodeExternalFunctionArguments(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms)}; if (first_deriv_symb_id == ExternalFunctionsTable::IDNotSet) { int nb_input_arguments{0}; @@ -8149,34 +8166,35 @@ SecondDerivExternalFunctionNode::computeXrefs(EquationInfo &ei) const } void -SecondDerivExternalFunctionNode::writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, +SecondDerivExternalFunctionNode::writeBytecodeOutput(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, - [[maybe_unused]] bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const { - if (steady_dynamic) + if (output_type == ExprNodeBytecodeOutputType::dynamicSteadyStateOperator) { cerr << "ERROR: The expression inside a steady_state operator cannot contain external functions" << endl; exit(EXIT_FAILURE); } - if (checkIfTemporaryTermThenWriteBytecode(code_file, temporary_terms, temporary_terms_idxs, dynamic, steady_dynamic)) + if (checkIfTemporaryTermThenWriteBytecode(code_file, output_type, temporary_terms, temporary_terms_idxs)) return; int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); assert(second_deriv_symb_id != ExternalFunctionsTable::IDSetButNoNameProvided); - if (!assignment_lhs) + if (!isAssignmentLHSBytecodeOutput(output_type)) code_file << FLDTEFDD_{getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2}; else code_file << FSTPTEFDD_{getIndxInTefTerms(symb_id, tef_terms), inputIndex1, inputIndex2}; } void -SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, bool assignment_lhs, +SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const { int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); @@ -8187,17 +8205,16 @@ SecondDerivExternalFunctionNode::writeBytecodeExternalFunctionOutput(BytecodeWri if (second_deriv_symb_id == symb_id) { expr_t parent = datatree.AddExternalFunction(symb_id, arguments); - parent->writeBytecodeExternalFunctionOutput(code_file, assignment_lhs, - temporary_terms, temporary_terms_idxs, - dynamic, steady_dynamic, tef_terms); + parent->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms); return; } if (alreadyWrittenAsTefTerm(second_deriv_symb_id, tef_terms)) return; - int nb_add_input_arguments{writeBytecodeExternalFunctionArguments(code_file, assignment_lhs, temporary_terms, - temporary_terms_idxs, dynamic, steady_dynamic, tef_terms)}; + int nb_add_input_arguments{writeBytecodeExternalFunctionArguments(code_file, output_type, temporary_terms, + temporary_terms_idxs, tef_terms)}; if (second_deriv_symb_id == ExternalFunctionsTable::IDNotSet) { int nb_input_arguments{0}; @@ -8433,11 +8450,9 @@ SubModelNode::collectDynamicVariables([[maybe_unused]] SymbolType type_arg, void SubModelNode::writeBytecodeOutput([[maybe_unused]] BytecodeWriter &code_file, - [[maybe_unused]] bool assignment_lhs, + [[maybe_unused]] ExprNodeBytecodeOutputType output_type, [[maybe_unused]] const temporary_terms_t &temporary_terms, [[maybe_unused]] const temporary_terms_idxs_t &temporary_terms_idxs, - [[maybe_unused]] bool dynamic, - [[maybe_unused]] bool steady_dynamic, [[maybe_unused]] const deriv_node_temp_terms_t &tef_terms) const { cerr << "SubModelNode::compile not implemented." << endl; diff --git a/src/ExprNode.hh b/src/ExprNode.hh index db608403a26b7cd1792b071e6e593755f3c32938..39b2781d22de55453684da1efebeb50792e304fd 100644 --- a/src/ExprNode.hh +++ b/src/ExprNode.hh @@ -80,7 +80,7 @@ using deriv_node_temp_terms_t = map<pair<int, vector<expr_t>>, int>; expressions with which they should be substituted. */ using lag_equivalence_table_t = map<expr_t, map<int, expr_t>>; -//! Possible types of output when writing ExprNode(s) +//! Possible types of output when writing ExprNode(s) (not used for bytecode) enum class ExprNodeOutputType { matlabStaticModel, //!< Matlab code, static model @@ -104,6 +104,16 @@ enum class ExprNodeOutputType occbinDifferenceFile //!< MATLAB, in the generated occbin_difference file }; +// Possible types of output when writing ExprNode(s) in bytecode +enum class ExprNodeBytecodeOutputType + { + dynamicModel, + staticModel, + dynamicSteadyStateOperator, // Inside a steady_state operator + dynamicAssignmentLHS, // Assignment of a dynamic variable on the LHS of a (recursive) equation + staticAssignmentLHS // Assignment of a static variable on the LHS of a (recursive) equation + }; + constexpr bool isMatlabOutput(ExprNodeOutputType output_type) { @@ -152,6 +162,13 @@ isSteadyStateOperatorOutput(ExprNodeOutputType output_type) || output_type == ExprNodeOutputType::juliaDynamicSteadyStateOperator; } +constexpr bool +isAssignmentLHSBytecodeOutput(ExprNodeBytecodeOutputType output_type) +{ + return output_type == ExprNodeBytecodeOutputType::staticAssignmentLHS + || output_type == ExprNodeBytecodeOutputType::dynamicAssignmentLHS; +} + /* Equal to 1 for Matlab langage or Julia, or to 0 for C language. Not defined for LaTeX. In Matlab and Julia, array indexes begin at 1, while they begin at 0 in C */ constexpr int @@ -252,9 +269,9 @@ protected: // Same as above, for the bytecode case bool checkIfTemporaryTermThenWriteBytecode(BytecodeWriter &code_file, + ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, - bool dynamic, bool steady_dynamic) const; + const temporary_terms_idxs_t &temporary_terms_idxs) const; // Internal helper for matchVariableTimesConstantTimesParam() virtual void matchVTCTPHelper(optional<int> &var_id, int &lag, optional<int> ¶m_id, double &constant, bool at_denominator) const; @@ -377,8 +394,9 @@ public: bool isdynamic = true) const; virtual void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const; //! Computes the set of all variables of a given symbol type in the expression (with information on lags) @@ -422,7 +440,9 @@ public: }; virtual double eval(const eval_context_t &eval_context) const noexcept(false) = 0; - virtual void writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const = 0; + + // Write output to bytecode file + virtual void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const = 0; //! Creates a static version of this node /*! @@ -804,7 +824,7 @@ public: void collectVARLHSVariable(set<expr_t> &result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override; double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const override; + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; expr_t toStatic(DataTree &static_datatree) const override; void computeXrefs(EquationInfo &ei) const override; void computeSubExprContainingVariable(int symb_id, int lag, set<expr_t> &contain_var) const override; @@ -876,7 +896,7 @@ public: void collectVARLHSVariable(set<expr_t> &result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override; double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const override; + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; expr_t toStatic(DataTree &static_datatree) const override; void computeXrefs(EquationInfo &ei) const override; SymbolType get_type() const; @@ -972,14 +992,15 @@ public: deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const override; + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, + deriv_node_temp_terms_t &tef_terms) const override; void collectVARLHSVariable(set<expr_t> &result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override; static double eval_opcode(UnaryOpcode op_code, double v) noexcept(false); double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const override; + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; expr_t toStatic(DataTree &static_datatree) const override; void computeXrefs(EquationInfo &ei) const override; void computeSubExprContainingVariable(int symb_id, int lag, set<expr_t> &contain_var) const override; @@ -1075,14 +1096,15 @@ public: deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const override; void collectVARLHSVariable(set<expr_t> &result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override; static double eval_opcode(double v1, BinaryOpcode op_code, double v2, int derivOrder) noexcept(false); double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const override; + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; expr_t Compute_RHS(expr_t arg1, expr_t arg2, int op, int op_type) const; expr_t toStatic(DataTree &static_datatree) const override; void computeXrefs(EquationInfo &ei) const override; @@ -1216,14 +1238,15 @@ public: deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const override; void collectVARLHSVariable(set<expr_t> &result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override; static double eval_opcode(double v1, TrinaryOpcode op_code, double v2, double v3) noexcept(false); double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const override; + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; expr_t toStatic(DataTree &static_datatree) const override; void computeXrefs(EquationInfo &ei) const override; void computeSubExprContainingVariable(int symb_id, int lag, set<expr_t> &contain_var) const override; @@ -1298,8 +1321,9 @@ protected: void writeJsonASTExternalFunctionArguments(ostream &output) const; void writeJsonExternalFunctionArguments(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const; int writeBytecodeExternalFunctionArguments(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const; /*! Returns a predicate that tests whether an other ExprNode is an external function which is computed by the same external function call (i.e. it has @@ -1328,13 +1352,14 @@ public: deriv_node_temp_terms_t &tef_terms, bool isdynamic = true) const override = 0; void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const override = 0; void collectVARLHSVariable(set<expr_t> &result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override; double eval(const eval_context_t &eval_context) const noexcept(false) override; - void writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const override = 0; + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override = 0; expr_t toStatic(DataTree &static_datatree) const override = 0; void computeXrefs(EquationInfo &ei) const override = 0; void computeSubExprContainingVariable(int symb_id, int lag, set<expr_t> &contain_var) const override; @@ -1409,10 +1434,11 @@ public: deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const override; - void writeBytecodeOutput(BytecodeWriter &code_file, bool assignment_lhs, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, const deriv_node_temp_terms_t &tef_terms) const override; + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; expr_t toStatic(DataTree &static_datatree) const override; void computeXrefs(EquationInfo &ei) const override; expr_t buildSimilarExternalFunctionNode(vector<expr_t> &alt_args, DataTree &alt_datatree) const override; @@ -1435,9 +1461,9 @@ public: void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; void writeJsonAST(ostream &output) const override; void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; - void writeBytecodeOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -1448,8 +1474,9 @@ public: deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const override; expr_t toStatic(DataTree &static_datatree) const override; void computeXrefs(EquationInfo &ei) const override; @@ -1475,9 +1502,9 @@ public: void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; void writeJsonAST(ostream &output) const override; void writeJsonOutput(ostream &output, const temporary_terms_t &temporary_terms, const deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; - void writeBytecodeOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -1488,8 +1515,9 @@ public: deriv_node_temp_terms_t &tef_terms, bool isdynamic) const override; void writeBytecodeExternalFunctionOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const override; expr_t toStatic(DataTree &static_datatree) const override; void computeXrefs(EquationInfo &ei) const override; @@ -1543,9 +1571,9 @@ public: expr_t substituteUnaryOpNodes(const lag_equivalence_table_t &nodes, subst_table_t &subst_table, vector<BinaryOpNode *> &neweqs) const override; void computeSubExprContainingVariable(int symb_id, int lag, set<expr_t> &contain_var) const override; BinaryOpNode *normalizeEquationHelper(const set<expr_t> &contain_var, expr_t rhs) const override; - void writeBytecodeOutput(BytecodeWriter &code_file, - bool assignment_lhs, const temporary_terms_t &temporary_terms, - const temporary_terms_idxs_t &temporary_terms_idxs, bool dynamic, bool steady_dynamic, + void writeBytecodeOutput(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, + const temporary_terms_t &temporary_terms, + const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const override; void collectVARLHSVariable(set<expr_t> &result) const override; void collectDynamicVariables(SymbolType type_arg, set<pair<int, int>> &result) const override; diff --git a/src/ModelTree.cc b/src/ModelTree.cc index 8a4f7b8999080f3f3288b8f766665d9fa21d0009..cd3ade622adfcd8f32e35c19e9eda11d236af4c7 100644 --- a/src/ModelTree.cc +++ b/src/ModelTree.cc @@ -1255,20 +1255,30 @@ ModelTree::testNestedParenthesis(const string &str) const } void -ModelTree::writeBytecodeTemporaryTerms(BytecodeWriter &code_file, bool dynamic, bool steady_dynamic, temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const +ModelTree::writeBytecodeTemporaryTerms(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const { // To store the functions that have already been written in the form TEF* = ext_fun(); for (auto [tt, idx] : temporary_terms_idxs) { if (dynamic_cast<AbstractExternalFunctionNode *>(tt)) - tt->writeBytecodeExternalFunctionOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + tt->writeBytecodeExternalFunctionOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FNUMEXPR_{ExpressionType::TemporaryTerm, idx}; - tt->writeBytecodeOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); - if (dynamic) - code_file << FSTPT_{idx}; - else - code_file << FSTPST_{idx}; + tt->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, tef_terms); + switch (output_type) + { + case ExprNodeBytecodeOutputType::dynamicModel: + code_file << FSTPT_{idx}; + break; + case ExprNodeBytecodeOutputType::staticModel: + code_file << FSTPST_{idx}; + break; + case ExprNodeBytecodeOutputType::dynamicSteadyStateOperator: + case ExprNodeBytecodeOutputType::dynamicAssignmentLHS: + case ExprNodeBytecodeOutputType::staticAssignmentLHS: + cerr << "ModelTree::writeBytecodeTemporaryTerms: impossible case" << endl; + exit(EXIT_FAILURE); + } } } @@ -1383,7 +1393,7 @@ ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type, } void -ModelTree::writeBytecodeModelEquations(BytecodeWriter &code_file, bool dynamic, bool steady_dynamic, const temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const +ModelTree::writeBytecodeModelEquations(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const { for (int eq = 0; eq < static_cast<int>(equations.size()); eq++) { @@ -1402,14 +1412,14 @@ ModelTree::writeBytecodeModelEquations(BytecodeWriter &code_file, bool dynamic, if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs; { - lhs->writeBytecodeOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + lhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, tef_terms); + rhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FBINARY_{BinaryOpcode::minus} << FSTPR_{eq}; } else // The right hand side of the equation is empty ==> residual=lhs; { - lhs->writeBytecodeOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, dynamic, steady_dynamic, tef_terms); + lhs->writeBytecodeOutput(code_file, output_type, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FSTPR_{eq}; } } diff --git a/src/ModelTree.hh b/src/ModelTree.hh index 93afa63de4c158da29da8aed3e8e131886e5c27b..de4968dd337941ed67c26dddcbc0042c173e1cd7 100644 --- a/src/ModelTree.hh +++ b/src/ModelTree.hh @@ -242,7 +242,7 @@ protected: void writeTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, const temporary_terms_idxs_t &tt_idxs, ostream &output, ExprNodeOutputType output_type, deriv_node_temp_terms_t &tef_terms) const; void writeJsonTemporaryTerms(const temporary_terms_t &tt, temporary_terms_t &temp_term_union, ostream &output, deriv_node_temp_terms_t &tef_terms, const string &concat) const; //! Writes temporary terms in bytecode - void writeBytecodeTemporaryTerms(BytecodeWriter &code_file, bool dynamic, bool steady_dynamic, temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const; + void writeBytecodeTemporaryTerms(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, deriv_node_temp_terms_t &tef_terms) const; //! Adds information for (non-block) bytecode simulation in a separate .bin file void writeBytecodeBinFile(const string &filename, int &u_count_int, bool &file_open, bool is_two_boundaries) const; //! Fixes output when there are more than 32 nested parens, Issue #1201 @@ -265,7 +265,7 @@ protected: Optionally put the external function variable calls into TEF terms */ void writeJsonModelLocalVariables(ostream &output, bool write_tef_terms, deriv_node_temp_terms_t &tef_terms) const; //! Writes model equations in bytecode - void writeBytecodeModelEquations(BytecodeWriter &code_file, bool dynamic, bool steady_dynamic, const temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const; + void writeBytecodeModelEquations(BytecodeWriter &code_file, ExprNodeBytecodeOutputType output_type, const temporary_terms_t &temporary_terms_union, const temporary_terms_idxs_t &temporary_terms_idxs, const deriv_node_temp_terms_t &tef_terms) const; //! Writes LaTeX model file void writeLatexModelFile(const string &mod_basename, const string &latex_basename, ExprNodeOutputType output_type, bool write_equation_tags) const; diff --git a/src/StaticModel.cc b/src/StaticModel.cc index a88e33dc67b50279c8e41412c7479ccd22254b59..3ffe961bdb12602c3d9b4207d27666de7101b1f5 100644 --- a/src/StaticModel.cc +++ b/src/StaticModel.cc @@ -99,7 +99,7 @@ StaticModel::writeBytecodeDerivative(BytecodeWriter &code_file, int eq, int symb { if (auto it = derivatives[1].find({ eq, getDerivID(symbol_table.getID(SymbolType::endogenous, symb_id), 0) }); it != derivatives[1].end()) - it->second->writeBytecodeOutput(code_file, false, temporary_terms, temporary_terms_idxs, false, false, tef_terms); + it->second->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms, temporary_terms_idxs, tef_terms); else code_file << FLDZ_{}; } @@ -109,7 +109,7 @@ StaticModel::writeBytecodeChainRuleDerivative(BytecodeWriter &code_file, int blk { if (auto it = blocks_derivatives[blk].find({ eq, var, lag }); it != blocks_derivatives[blk].end()) - it->second->writeBytecodeOutput(code_file, false, temporary_terms, temporary_terms_idxs, false, false, tef_terms); + it->second->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms, temporary_terms_idxs, tef_terms); else code_file << FLDZ_{}; } @@ -397,9 +397,9 @@ StaticModel::writeStaticBytecode(const string &basename) const temporary_terms_t temporary_terms_union; deriv_node_temp_terms_t tef_terms; - writeBytecodeTemporaryTerms(code_file, false, false, temporary_terms_union, temporary_terms_idxs, tef_terms); + writeBytecodeTemporaryTerms(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, temporary_terms_idxs, tef_terms); - writeBytecodeModelEquations(code_file, false, false, temporary_terms_union, temporary_terms_idxs, tef_terms); + writeBytecodeModelEquations(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FENDEQU_{}; @@ -422,7 +422,7 @@ StaticModel::writeStaticBytecode(const string &basename) const my_derivatives[eq].clear(); my_derivatives[eq].emplace_back(var, count_u); - d1->writeBytecodeOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, false, false, tef_terms); + d1->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FSTPSU_{count_u}; count_u++; @@ -469,7 +469,7 @@ StaticModel::writeStaticBytecode(const string &basename) const my_derivatives[eq].clear(); my_derivatives[eq].emplace_back(var, count_u); - d1->writeBytecodeOutput(code_file, false, temporary_terms_union, temporary_terms_idxs, false, false, tef_terms); + d1->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, temporary_terms_idxs, tef_terms); code_file << FSTPG2_{eq, var}; } } @@ -561,10 +561,10 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const for (auto it : blocks_temporary_terms[block][eq]) { if (dynamic_cast<AbstractExternalFunctionNode *>(it)) - it->writeBytecodeExternalFunctionOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); + it->writeBytecodeExternalFunctionOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FNUMEXPR_{ExpressionType::TemporaryTerm, blocks_temporary_terms_idxs.at(it)}; - it->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); + it->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FSTPST_{blocks_temporary_terms_idxs.at(it)}; temporary_terms_union.insert(it); } @@ -589,16 +589,16 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const eq_node = getBlockEquationExpr(block, i); lhs = eq_node->arg1; rhs = eq_node->arg2; - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); - lhs->writeBytecodeOutput(code_file, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); + rhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + lhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticAssignmentLHS, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); } else if (equ_type == EquationType::evaluateRenormalized) { eq_node = getBlockEquationRenormalizedExpr(block, i); lhs = eq_node->arg1; rhs = eq_node->arg2; - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); - lhs->writeBytecodeOutput(code_file, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); + rhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + lhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticAssignmentLHS, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); } break; case BlockSimulationType::solveBackwardComplete: @@ -616,8 +616,8 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const eq_node = getBlockEquationExpr(block, i); lhs = eq_node->arg1; rhs = eq_node->arg2; - lhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); + lhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + rhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FBINARY_{BinaryOpcode::minus} << FSTPR_{i - block_recursive}; } @@ -724,16 +724,16 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const eq_node = getBlockEquationExpr(block, i); lhs = eq_node->arg1; rhs = eq_node->arg2; - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); - lhs->writeBytecodeOutput(code_file, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); + rhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + lhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticAssignmentLHS, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); } else if (equ_type == EquationType::evaluateRenormalized) { eq_node = getBlockEquationRenormalizedExpr(block, i); lhs = eq_node->arg1; rhs = eq_node->arg2; - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); - lhs->writeBytecodeOutput(code_file, true, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); + rhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + lhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticAssignmentLHS, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); } break; case BlockSimulationType::solveBackwardComplete: @@ -751,8 +751,8 @@ StaticModel::writeStaticBlockBytecode(const string &basename) const eq_node = getBlockEquationExpr(block, i); lhs = eq_node->arg1; rhs = eq_node->arg2; - lhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); - rhs->writeBytecodeOutput(code_file, false, temporary_terms_union, blocks_temporary_terms_idxs, false, false, tef_terms); + lhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); + rhs->writeBytecodeOutput(code_file, ExprNodeBytecodeOutputType::staticModel, temporary_terms_union, blocks_temporary_terms_idxs, tef_terms); code_file << FBINARY_{BinaryOpcode::minus} << FSTPR_{i - block_recursive}; }