From 9b9c5beb5ce4e9b476730862db82fd5c87db526d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= Date: Mon, 19 Aug 2019 18:23:56 +0200 Subject: [PATCH] Ensure that unary ops aux vars are never created when there is a lead MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The transformation would be incorrect because of the expectation operator. There was already a safety check, but it was not entirely correct. For example, if “exp(y)” was appearing before “exp(y(+1))”, the check would not catch the problem, because it happened after the substitution table had been filled. So we now do the check before filling that table. --- src/ExprNode.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/ExprNode.cc b/src/ExprNode.cc index 7ab4e100..8680e660 100644 --- a/src/ExprNode.cc +++ b/src/ExprNode.cc @@ -3599,12 +3599,6 @@ UnaryOpNode::substituteUnaryOpNodes(DataTree &static_datatree, diff_table_t &nod if (it == nodes.end()) return buildSimilarUnaryOpNode(argsubst, datatree); - if (arg->maxLead() > 0) - { - cerr << "Cannot substitute unary operations that contain leads" << endl; - exit(EXIT_FAILURE); - } - string unary_op; switch (op_code) { @@ -3682,6 +3676,16 @@ UnaryOpNode::substituteUnaryOpNodes(DataTree &static_datatree, diff_table_t &nod for (auto rit = it->second.rbegin(); rit != it->second.rend(); ++rit) if (rit == it->second.rbegin()) { + /* Verify that we’re not operating on a node with leads, since the + transformation does take into account the expectation operator. We only + need to do this for the first iteration of the loop, because we’re + going from leads to lags. */ + if (rit->second->maxLead() > 0) + { + cerr << "Cannot substitute unary operations that contain leads" << endl; + exit(EXIT_FAILURE); + } + int symb_id; auto *vn = dynamic_cast(argsubst); if (vn == nullptr)