From d747b53a8b106d8f7c50442c0dff589d7ac1b613 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Thu, 12 Dec 2019 13:06:50 +0100
Subject: [PATCH] Simplify x*y/y in x
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Note that this actually corresponds to 4 different abstract syntax trees:
— (x*y)/y
— (y*x)/y
— (x/y)*y
— y*(x/y)
---
 src/DataTree.cc | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/src/DataTree.cc b/src/DataTree.cc
index 3574b557..1887d627 100644
--- a/src/DataTree.cc
+++ b/src/DataTree.cc
@@ -243,6 +243,16 @@ DataTree::AddTimes(expr_t iArg1, expr_t iArg2)
     return AddUMinus(iArg1);
   else if (iArg1 != Zero && iArg1 != One && iArg2 != Zero && iArg2 != One)
     {
+      // Simplify (x/y)*y in x
+      if (auto barg1 = dynamic_cast<BinaryOpNode *>(iArg1);
+          barg1 && barg1->op_code == BinaryOpcode::divide && barg1->arg2 == iArg2)
+        return barg1->arg1;
+
+      // Simplify y*(x/y) in x
+      if (auto barg2 = dynamic_cast<BinaryOpNode *>(iArg2);
+          barg2 && barg2->op_code == BinaryOpcode::divide && barg2->arg2 == iArg1)
+        return barg2->arg1;
+
       // To treat commutativity of "*"
       // Nodes iArg1 and iArg2 are sorted by index
       if (iArg1->idx > iArg2->idx)
@@ -283,6 +293,16 @@ DataTree::AddDivide(expr_t iArg1, expr_t iArg2) noexcept(false)
       barg2 && barg2->op_code == BinaryOpcode::divide && barg2->arg1 == One)
     return AddTimes(iArg1, barg2->arg2);
 
+  // Simplify (x*y)/y and (y*x)/y in x
+  if (auto barg1 = dynamic_cast<BinaryOpNode *>(iArg1);
+      barg1 && barg1->op_code == BinaryOpcode::times)
+    {
+      if (barg1->arg2 == iArg2)
+        return barg1->arg1;
+      if (barg1->arg1 == iArg2)
+        return barg1->arg2;
+    }
+
   return AddBinaryOp(iArg1, BinaryOpcode::divide, iArg2);
 }
 
-- 
GitLab