{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "nbsphinx": "hidden"
   },
   "outputs": [],
   "source": [
    "from pystencils.session import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Demo: Assignment collections and simplification\n",
    "\n",
    "\n",
    "## Assignment collections\n",
    "\n",
    "The assignment collection class helps to formulate and simplify assignments for numerical kernels. \n",
    "\n",
    "An ``AssignmentCollection`` is an ordered collection of assignments, together with an optional ordered collection of subexpressions, that are required to evaluate the main assignments. There are various simplification rules available that operate on ``AssignmentCollection``s."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We start by defining some stencil update rule. Here we also use the *pystencils* ``Field``, note however that the assignment collection module works purely on the *sympy* level."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>Main Assignments:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} \\left(a^{2} - c\\right) + {f}_{(0,1)}^{0} \\left(a^{2} + b\\right) + {f}_{(0,-1)}^{0} a^{2} + {f}_{(-1,0)}^{0} \\left(a^{2} - 2 c\\right)$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{0} \\leftarrow_{} {f}_{(1,0)}^{0} \\left(c^{2} - c\\right) + {f}_{(0,1)}^{0} \\left(b + c^{2}\\right) + {f}_{(0,-1)}^{0} \\left(- a^{2} + c^{2}\\right) + {f}_{(-1,0)}^{0} \\left(c^{2} - 2 c\\right)$$</td>  </tr> </table>"
      ],
      "text/plain": [
       "AssignmentCollection: g_C^0, g_C^1 <- f(f_N^0, b, f_S^0, f_E^0, a, f_W^0, c)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a,b,c = sp.symbols(\"a b c\")\n",
    "f = ps.fields(\"f(2) : [2D]\")\n",
    "g = ps.fields(\"g(2) : [2D]\")\n",
    "\n",
    "a1 = ps.Assignment(g[0,0](1), (a**2 +b) * f[0,1] + \\\n",
    "                  (a**2 - c) * f[1,0] + \\\n",
    "                  (a**2 - 2*c) * f[-1,0] + \\\n",
    "                  (a**2) * f[0, -1])\n",
    "\n",
    "a2 = ps.Assignment(g[0,0](0), (c**2 +b) * f[0,1] + \\\n",
    "                  (c**2 - c) * f[1,0] + \\\n",
    "                  (c**2 - 2*c) * f[-1,0] + \\\n",
    "                  (c**2 - a**2) * f[0, -1])\n",
    "\n",
    "\n",
    "ac = ps.AssignmentCollection([a1, a2], subexpressions=[])\n",
    "ac"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*sympy* operations can be applied on an assignment collection: In this example we first expand the collection, then look for common subexpressions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "expand_all = ps.simp.apply_to_all_assignments(sp.expand)\n",
    "expandedEc = expand_all(ac)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>Subexpressions:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{0} \\leftarrow_{} a^{2}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{1} \\leftarrow_{} {f}_{(0,-1)}^{0} \\xi_{0}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{2} \\leftarrow_{} - {f}_{(1,0)}^{0} c + {f}_{(0,1)}^{0} b - 2 {f}_{(-1,0)}^{0} c$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{3} \\leftarrow_{} c^{2}$$</td>  </tr> </table><div>Main Assignments:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{0} + {f}_{(0,1)}^{0} \\xi_{0} + {f}_{(-1,0)}^{0} \\xi_{0} + \\xi_{1} + \\xi_{2}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{0} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{3} + {f}_{(0,1)}^{0} \\xi_{3} + {f}_{(0,-1)}^{0} \\xi_{3} + {f}_{(-1,0)}^{0} \\xi_{3} - \\xi_{1} + \\xi_{2}$$</td>  </tr> </table>"
      ],
      "text/plain": [
       "AssignmentCollection: g_C^0, g_C^1 <- f(f_N^0, b, f_S^0, f_E^0, a, f_W^0, c)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ac_cse = ps.simp.sympy_cse(expandedEc)\n",
    "ac_cse"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Symbols occuring in assignment collections are classified into 3 categories:\n",
    "- ``free_symbols``: symbols that occur in right-hand-sides but never on left-hand-sides\n",
    "- ``bound_symbols``: symbols that occur on left-hand-sides\n",
    "- ``defined_symbols``: symbols that occur on left-hand-sides of a main assignment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left\\{{f}_{(1,0)}^{0}, {f}_{(0,1)}^{0}, {f}_{(0,-1)}^{0}, {f}_{(-1,0)}^{0}, a, b, c\\right\\}$"
      ],
      "text/plain": [
       "{f_E__0, f_N__0, f_S__0, f_W__0, a, b, c}"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ac_cse.free_symbols"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left\\{{g}_{(0,0)}^{0}, {g}_{(0,0)}^{1}, \\xi_{0}, \\xi_{1}, \\xi_{2}, \\xi_{3}\\right\\}$"
      ],
      "text/plain": [
       "{g_C__0, g_C__1, ξ₀, ξ₁, ξ₂, ξ₃}"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ac_cse.bound_symbols"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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",
      "text/latex": [
       "$\\displaystyle \\left\\{{g}_{(0,0)}^{0}, {g}_{(0,0)}^{1}\\right\\}$"
      ],
      "text/plain": [
       "{g_C__0, g_C__1}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ac_cse.defined_symbols"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Assignment collections can be splitted up, and merged together. For splitting, a list of symbols that occur on the left-hand-side in the main assignments has to be passed. The returned assignment collection only contains these main assignments together with all necessary subexpressions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>Subexpressions:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{0} \\leftarrow_{} a^{2}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{1} \\leftarrow_{} {f}_{(0,-1)}^{0} \\xi_{0}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{2} \\leftarrow_{} - {f}_{(1,0)}^{0} c + {f}_{(0,1)}^{0} b - 2 {f}_{(-1,0)}^{0} c$$</td>  </tr> </table><div>Main Assignments:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{0} + {f}_{(0,1)}^{0} \\xi_{0} + {f}_{(-1,0)}^{0} \\xi_{0} + \\xi_{1} + \\xi_{2}$$</td>  </tr> </table>"
      ],
      "text/plain": [
       "AssignmentCollection: g_C^1, <- f(f_N^0, b, f_S^0, f_E^0, a, f_W^0, c)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ac_f0 = ac_cse.new_filtered([g(0)])\n",
    "ac_f1 = ac_cse.new_filtered([g(1)])\n",
    "ac_f1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note here that $\\xi_4$ is no longer part of the subexpressions, since it is not used in the main assignment of $f_C^1$.\n",
    "\n",
    "If we merge both collections together, we end up with the original collection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>Subexpressions:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{0} \\leftarrow_{} a^{2}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{1} \\leftarrow_{} {f}_{(0,-1)}^{0} \\xi_{0}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{2} \\leftarrow_{} - {f}_{(1,0)}^{0} c + {f}_{(0,1)}^{0} b - 2 {f}_{(-1,0)}^{0} c$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{3} \\leftarrow_{} c^{2}$$</td>  </tr> </table><div>Main Assignments:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{0} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{3} + {f}_{(0,1)}^{0} \\xi_{3} + {f}_{(0,-1)}^{0} \\xi_{3} + {f}_{(-1,0)}^{0} \\xi_{3} - \\xi_{1} + \\xi_{2}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{0} + {f}_{(0,1)}^{0} \\xi_{0} + {f}_{(-1,0)}^{0} \\xi_{0} + \\xi_{1} + \\xi_{2}$$</td>  </tr> </table>"
      ],
      "text/plain": [
       "AssignmentCollection: g_C^0, g_C^1 <- f(f_N^0, b, f_S^0, f_E^0, a, f_W^0, c)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ac_f0.new_merged(ac_f1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There is also a method that inserts all subexpressions into the main assignments. This is the inverse operation of common subexpression elimination."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>Main Assignments:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{0} \\leftarrow_{} {f}_{(1,0)}^{0} c^{2} - {f}_{(1,0)}^{0} c + {f}_{(0,1)}^{0} b + {f}_{(0,1)}^{0} c^{2} - {f}_{(0,-1)}^{0} a^{2} + {f}_{(0,-1)}^{0} c^{2} + {f}_{(-1,0)}^{0} c^{2} - 2 {f}_{(-1,0)}^{0} c$$</td>  </tr> </table>"
      ],
      "text/plain": [
       "AssignmentCollection: g_C^0, <- f(f_N^0, b, f_S^0, f_E^0, a, f_W^0, c)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "assert sp.simplify(ac_f0.new_without_subexpressions().main_assignments[0].rhs - a2.rhs) == 0\n",
    "ac_f0.new_without_subexpressions()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To evaluate an assignment collection, use the ``lambdify`` method. It is very similar to *sympy*s ``lambdify`` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAN4AAAAmCAYAAACrpiXDAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAIy0lEQVR4Ae2d65VTNxDHlz0UwKOCQAc8KgA6gKQCoANy+MY3DnQAqSBAB0AFCXQQUgHEHWz+P1kSkq50LdnX9rWtOUfWa0aPGY1Gr7t76eLi4qwEL168eKa8p3KPFP5awuvpnQOdA0sOSE+eKPS73CuF35b4cimneCK4IYKPcgs5lO5bqYCe3jnQORBzQPpyXylv5NCfe4rjRzBQPKt0X4T1SeFHEXaPdA50DlRxQLpzRYjo0ZnCN1Oi8zRB8VdyED3O5PWkzoHOgQoOSNmwcmzTbijM8jOCnOLdEsZXSxgh90jnQOdAPQekQ5+EjQLeTqkupwmKX5Ob7CBFlWNBge9y1xVn49lhTxwQ/1nN/Cr3VOHBgNhTs469WnQqgpzFixA2iUiwmNjvKJvca4U/yufQpsMeOCDes5pBJigfrsOeOLBVxVOfsHaYWwMSPOH78m/YpO7tkAPiO1sIJsB+Sr1Dvueq2priWeViVk2FvFAaM2+HzoGT5UBujzcVM0pLmR+qYLDmnarSbZdjJxTuad4pzCRSBOXfkov2y4rDl2vy0wmpWE7P2C8HJCtWaFUyr23pNhWv1AaUrqSUJZo5pWOtuRx9I4Hk2rVQ+lWb8Vlh+uqUz/W7H2rkOLfHNMkJub6Xu63wImlKi8wT0nx0m4qXNt61gMF3yLP9XbWfvWquD8yK4akt1h1AcOB/kHuZEaySO+yaA3ZS/EP1Iqc7cqWzhxaZV3Vja4qnTn2zA4zOuBnfNSqNu/SD8NWvB2lDlWaEJh/lcsBhRn/947gxM1+ywTgY+SjMu2QmyCwov1bmWfo08TxNmDj+UuVhBQyo8YQ/yM9ZC4s1e++vQgt5FMtLhQ7Hx4HJZZ6zeCwFJwENxNdyDEiuFbhA583aQT9FU19Ci2b4ZPvHJDNrUDuxykwOTIA8ZTJykc8VQ4cCB8SfTWTOMtashsLiI8VTBc7UVl9yi+ahCmQNjGIBNJK7OvNJhPxwz2MQ5vajNv6jNvEovNliiQamcnqZ7afS3YX1deGByx5vK0ttlbtKFqw0su1U+mxA/VhbHrvohNo3KvOkDejDM9FckfPnHucJEhtN9iXF74hCfOExYz6X716mUAkvsg9mX6O2Y+FhJJvrdQAe4HJA2Vw7YPkZ8LgvCmNxJgWVefCygCHqx6bymJSvhcLGZB6RqD/InAmPE1MPRvHorJyzcvd87khA+MyubEg9vtKoAMa5shScN6jNC7XwqvzmI37RoLBYd/86J+yt0h/IUb4BheEPuFxHTAYq9yhkAUMsv9aSx2QMHSlI7RuVeYGUscXdLU8m0Y+zywow+7p7qZa1PtaRg5JwYLml6mBNLNzZQtiHxkayNEWZWgB8lJU9VittqZ6jkQUdrJWH8BjEn+XMYIa2Ajb9awrNMrf94X6Qbcd/8m+zx0P4KM9NOmKRFC2DcFAwOvtngoUSc4E8GFBKY1ZmGTvIS8pYK6pyWUe3TBxr1ZMQ0adsf9QWrD6zXMmStgyWpNqfUZV/srJQ3xm3Jf7+ZNK0oaLMx6pRW6Ez2w2Fv2LxGDhoI+vWf+Xzqfqqzf8dW0mKx13HYNml8tB07vX8IFWY+oDqz4XGaJTHPorXJM0HJMtmtP2qHhSHZUfKA1cQPPrhIoF/jbDoS3QBalXw5GVRxaUJkCpknq1FdIx1dMDr1rnDVCbaiNJguqtANKEiMRCxeNH+zjaWvY5XSIVpRNPnQpU074XnFLqqDxsguQGfUy6Kfau2DD75Vzo88rwAUXgbWz+VccqygI27gFUyH7RBckHenIVES1yveJYC5WO5CeIYvCNTeMz4DthnACZvGTS/KEJ6mECaH3wqh/D9pDxDHPyspAnKqR7IoqG/F3KcxraAq2NRIML6Rv1W3PHVn/oqjXJY97fW76o9GlnQIfght448HD/W9a9bQrMiKRSySuY5MnOqqT758Q5SpHjKZNZkIHEvVwThgcOykstx9lYoBTO/eyamoAcUyleqMMpKB/wMbTEpk/3KABppjBIPCikkqGzqpS1/F1BKySwVoc2+alC5lAl/jALK5zgZC/iLrVNBM9Bc/Qy4Kyax4ceWdRSySPjRKo8Grv1ERS44pbAKA0xcaS6+TF3+jso8RAzCWMl0rJ9dDhCagmoYAzxUKGZsH6cw4aBkDKwQSoMLxS3NNi00KAIDsfpkVe3MLQnDNg/CooGZ7iuEQT4JFmflnpP65R5mC6lIFO3RyMLyrVkeFWzKooh3fvWRRQgShbtS5gH6aLBZ8VQ5Vum53GOFjVLZNNIfJ7WheChUDaB0JQUr0edoaBP1HhrcFR+rJws6Z/neZTF/SRs9CZt5HkYqwwiaDaMBCR9lYX/H6xVMcQjkpZWmcYcP7sAk28wWmlpFd/Xu3bc85HS3FbosWjk2E/x1FO+N2s7S5okGDHs7nHsypmAEKBIK5UE0pKFIOauUKq6ha6Sh3JICm/Jm+AMv17mD7LKYoTBrmrTOUjPaT4xVosHEhXlOwV6KDqtpFE04hP3nQoqjrOYNqHwHozQOST718cj2YED9XUfpzkTXZXEwUo4beh5HtxLjpDNSPjvQ+Bub5lRUtbLBDfeH4GMF/IFDBY1rfNPBiiM6Eb/LYiaCbrZ4a7SbpSgne9xneJAiRXGfoYDysIQ8lPWKR77iRRqbb5a1wju0pSbN3wV0WeyCyxV1bN3iSQlYDnFHFVm9VW0TPstPaFvADawWmpPB7bKYj6hzisepYHQgsmlzJXAsHn8yvKVcXu8vausWLheeXH52azfCNPGny2KEP7vKyikeg537sUlBAh9dJqaVCb/qY9yAjg9OWy1kQH46wS6L3chafMbQ4DBmEeT+Px7LNd4U8pqiW4+IXT3SOVDPAelPUZdyFo9jexTOfy1bX1XH7BzoHIADUjqMFy77H5UHFs8SYR55OMoDTy7HW5d9FNOhc+DkOCBd4ekkugNEnwItk5a/WcVzCCqE4/zf5Lb2l7FcXd3vHDgGDljF4y8PjJ43/A/jETcc6RWvLAAAAABJRU5ErkJggg==",
      "text/latex": [
       "$\\displaystyle \\left\\{ {g}_{(0,0)}^{0} : 75, \\  {g}_{(0,0)}^{1} : -17\\right\\}$"
      ],
      "text/plain": [
       "{g_C__0: 75, g_C__1: -17}"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "evalFct = ac_cse.lambdify([f[0,1], f[1,0]],  # new parameters of returned function\n",
    "                          fixed_symbols={a:1, b:2, c:3, f[0,-1]: 4, f[-1,0]: 5}) # fix values of other symbols\n",
    "evalFct(2,1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "lambdify is rather slow for evaluation. The intended way to evaluate an assignment collection is *pystencils* i.e. create a fast kernel, that applies the update at every site of a structured grid. The collection can be directly passed to the `create_kernel` function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "func = ps.create_kernel(ac_cse).compile()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Simplification Strategies\n",
    "\n",
    "In above examples, we already applied simplification rules to assignment collections. Simplification rules are functions that take, as a single argument, an assignment collection and return an modified/simplified copy of it. The ``SimplificationStrategy`` class holds a list of simplification rules and can apply all of them in the specified order. Additionally it provides useful printing and reporting functions. \n",
    "\n",
    "We start by creating a simplification strategy, consisting of the expand and CSE simplifications we have already applied above:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "strategy = ps.simp.SimplificationStrategy()\n",
    "strategy.add(ps.simp.apply_to_all_assignments(sp.expand))\n",
    "strategy.add(ps.simp.sympy_cse)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This strategy can be applied to any assignment collection:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>Subexpressions:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{0} \\leftarrow_{} a^{2}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{1} \\leftarrow_{} {f}_{(0,-1)}^{0} \\xi_{0}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{2} \\leftarrow_{} - {f}_{(1,0)}^{0} c + {f}_{(0,1)}^{0} b - 2 {f}_{(-1,0)}^{0} c$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{3} \\leftarrow_{} c^{2}$$</td>  </tr> </table><div>Main Assignments:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{0} + {f}_{(0,1)}^{0} \\xi_{0} + {f}_{(-1,0)}^{0} \\xi_{0} + \\xi_{1} + \\xi_{2}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{0} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{3} + {f}_{(0,1)}^{0} \\xi_{3} + {f}_{(0,-1)}^{0} \\xi_{3} + {f}_{(-1,0)}^{0} \\xi_{3} - \\xi_{1} + \\xi_{2}$$</td>  </tr> </table>"
      ],
      "text/plain": [
       "AssignmentCollection: g_C^0, g_C^1 <- f(f_N^0, b, f_S^0, f_E^0, a, f_W^0, c)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "strategy(ac)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The strategy can also print the simplification results at each stage. \n",
    "The report contains information about the number of operations after each simplification as well as the runtime of each simplification routine."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table style=\"border:none\"><tr><th>Name</th><th>Runtime</th><th>Adds</th><th>Muls</th><th>Divs</th><th>Total</th></tr><tr><td>OriginalTerm</td><td>-</td> <td>13</td> <td>19</td> <td>0</td>  <td>32</td> </tr><tr><td>expand</td><td>0.03 ms</td> <td>13</td> <td>26</td> <td>0</td>  <td>39</td> </tr><tr><td>sympy_cse</td><td>0.52 ms</td> <td>11</td> <td>14</td> <td>0</td>  <td>25</td> </tr></table>"
      ],
      "text/plain": [
       "<pystencils.simp.simplificationstrategy.SimplificationStrategy.create_simplification_report.<locals>.Report at 0x147de3e90>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "strategy.create_simplification_report(ac)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The strategy can also print the full collection after each simplification..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<h5 style=\"padding-bottom:10px\">Initial Version</h5> <div style=\"padding-left:20px;\"><div>Main Assignments:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} \\left(a^{2} - c\\right) + {f}_{(0,1)}^{0} \\left(a^{2} + b\\right) + {f}_{(0,-1)}^{0} a^{2} + {f}_{(-1,0)}^{0} \\left(a^{2} - 2 c\\right)$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{0} \\leftarrow_{} {f}_{(1,0)}^{0} \\left(c^{2} - c\\right) + {f}_{(0,1)}^{0} \\left(b + c^{2}\\right) + {f}_{(0,-1)}^{0} \\left(- a^{2} + c^{2}\\right) + {f}_{(-1,0)}^{0} \\left(c^{2} - 2 c\\right)$$</td>  </tr> </table></div><h5 style=\"padding-bottom:10px\">expand</h5> <div style=\"padding-left:20px;\"><div>Main Assignments:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} a^{2} - {f}_{(1,0)}^{0} c + {f}_{(0,1)}^{0} a^{2} + {f}_{(0,1)}^{0} b + {f}_{(0,-1)}^{0} a^{2} + {f}_{(-1,0)}^{0} a^{2} - 2 {f}_{(-1,0)}^{0} c$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{0} \\leftarrow_{} {f}_{(1,0)}^{0} c^{2} - {f}_{(1,0)}^{0} c + {f}_{(0,1)}^{0} b + {f}_{(0,1)}^{0} c^{2} - {f}_{(0,-1)}^{0} a^{2} + {f}_{(0,-1)}^{0} c^{2} + {f}_{(-1,0)}^{0} c^{2} - 2 {f}_{(-1,0)}^{0} c$$</td>  </tr> </table></div><h5 style=\"padding-bottom:10px\">sympy_cse</h5> <div style=\"padding-left:20px;\"><div>Subexpressions:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{0} \\leftarrow_{} a^{2}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{1} \\leftarrow_{} {f}_{(0,-1)}^{0} \\xi_{0}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{2} \\leftarrow_{} - {f}_{(1,0)}^{0} c + {f}_{(0,1)}^{0} b - 2 {f}_{(-1,0)}^{0} c$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$$\\xi_{3} \\leftarrow_{} c^{2}$$</td>  </tr> </table><div>Main Assignments:</div><table style=\"border:none; width: 100%; \"><tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{0} + {f}_{(0,1)}^{0} \\xi_{0} + {f}_{(-1,0)}^{0} \\xi_{0} + \\xi_{1} + \\xi_{2}$$</td>  </tr> <tr style=\"border:none\"> <td style=\"border:none\">$${g}_{(0,0)}^{0} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{3} + {f}_{(0,1)}^{0} \\xi_{3} + {f}_{(0,-1)}^{0} \\xi_{3} + {f}_{(-1,0)}^{0} \\xi_{3} - \\xi_{1} + \\xi_{2}$$</td>  </tr> </table></div>"
      ],
      "text/plain": [
       "<pystencils.simp.simplificationstrategy.SimplificationStrategy.show_intermediate_results.<locals>.IntermediateResults at 0x147e09c90>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "strategy.show_intermediate_results(ac)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "... or only specific assignments for better readability"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<h5 style=\"padding-bottom:10px\">Initial Version</h5> <div style=\"padding-left:20px;\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} \\left(a^{2} - c\\right) + {f}_{(0,1)}^{0} \\left(a^{2} + b\\right) + {f}_{(0,-1)}^{0} a^{2} + {f}_{(-1,0)}^{0} \\left(a^{2} - 2 c\\right)$$</div><h5 style=\"padding-bottom:10px\">expand</h5> <div style=\"padding-left:20px;\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} a^{2} - {f}_{(1,0)}^{0} c + {f}_{(0,1)}^{0} a^{2} + {f}_{(0,1)}^{0} b + {f}_{(0,-1)}^{0} a^{2} + {f}_{(-1,0)}^{0} a^{2} - 2 {f}_{(-1,0)}^{0} c$$</div><h5 style=\"padding-bottom:10px\">sympy_cse</h5> <div style=\"padding-left:20px;\">$${g}_{(0,0)}^{1} \\leftarrow_{} {f}_{(1,0)}^{0} \\xi_{0} + {f}_{(0,1)}^{0} \\xi_{0} + {f}_{(-1,0)}^{0} \\xi_{0} + \\xi_{1} + \\xi_{2}$$</div>"
      ],
      "text/plain": [
       "<pystencils.simp.simplificationstrategy.SimplificationStrategy.show_intermediate_results.<locals>.IntermediateResults at 0x1265a1b90>"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "strategy.show_intermediate_results(ac, symbols=[g(1)])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}