From 47b6abb42921c8d3d93790cab246d016bd33fea7 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 9 Sep 2024 21:48:24 +0000 Subject: [PATCH] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/explanation/2023_07_presentation.ipynb | 23978 ++++++++-------- .../2023_11_09_portland_state.ipynb | 18 +- docs/explanation/2023_11_17_pytensor.ipynb | 5044 ++-- .../2023_11_pydata_lightning_talk.ipynb | 26 +- docs/explanation/pldi_2023_presentation.ipynb | 9641 ++++--- docs/tutorials/getting-started.ipynb | 17 +- docs/tutorials/sklearn.ipynb | 13213 ++++----- python/tests/conftest.py | 2 +- 8 files changed, 25927 insertions(+), 26012 deletions(-) diff --git a/docs/explanation/2023_07_presentation.ipynb b/docs/explanation/2023_07_presentation.ipynb index 2eacbf4f..94c59aa4 100644 --- a/docs/explanation/2023_07_presentation.ipynb +++ b/docs/explanation/2023_07_presentation.ipynb @@ -1,12126 +1,12094 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```{post} 2023-07-20\n", - ":author: Saul\n", - "```\n" - ] - }, - { - "cell_type": "markdown", - "id": "a611c138-1afd-4d6f-9578-4f358d2438eb", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "```{eval-rst}\n", - "`Presentation as HTML <../2023_07_presentation.slides.html>`_\n", - "```\n" - ] - }, + "cells": [ + { + "cell_type": "markdown", + "id": "7fb27b941602401d91542211134fc71a", + "metadata": {}, + "source": [ + "```{post} 2023-07-20\n", + ":author: Saul\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "a611c138-1afd-4d6f-9578-4f358d2438eb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "source": [ + "```{eval-rst}\n", + "`Presentation as HTML <../2023_07_presentation.slides.html>`_\n", + "```\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "acae54e37e7d407bbb7b55eff062a284", + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [ - { - "data": { - "image/jpeg": "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", - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/jpeg": "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", + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "from IPython.display import YouTubeVideo\n", - "\n", - "YouTubeVideo(\"Pbi2uV9vWPg\")" + "text/plain": [ + "" ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "68dd13a3-5864-4764-a528-1eedac698723", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "# EGraphs in Python\n", - "\n", - "- Overview of the ecosystem\n", - "- What is an e-graph?\n", - "- What is egglog?\n", - "- What are some possible applications in the PyData world?\n" - ] - }, + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import YouTubeVideo\n", + "\n", + "YouTubeVideo(\"Pbi2uV9vWPg\")" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "68dd13a3-5864-4764-a528-1eedac698723", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "# EGraphs in Python\n", + "\n", + "- Overview of the ecosystem\n", + "- What is an e-graph?\n", + "- What is egglog?\n", + "- What are some possible applications in the PyData world?\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1f7b1c58-0f6f-4d43-a8b0-c04b5d2f5b08", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [ + "remove-input" + ] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 1, - "id": "1f7b1c58-0f6f-4d43-a8b0-c04b5d2f5b08", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [ - "remove-input" - ] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_9\n", - "\n", - "\n", - "cluster_9\n", - "\n", - "\n", - "\n", - "outer_cluster_py_ndarray_12463696466920899969_0\n", - "\n", - "\n", - "cluster_py_ndarray_12463696466920899969_0\n", - "\n", - "\n", - "\n", - "outer_cluster_py_value_8004441328793213481_0\n", - "\n", - "\n", - "cluster_py_value_8004441328793213481_0\n", - "\n", - "\n", - "\n", - "outer_cluster_py_ndarray_2781105897590886682_0\n", - "\n", - "\n", - "cluster_py_ndarray_2781105897590886682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_py_value_5338970148915291456_0\n", - "\n", - "\n", - "cluster_py_value_5338970148915291456_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Values.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___0_0\n", - "\n", - "\n", - "cluster_Value.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___5871781006564002453_0:s->NDArray.__getitem___13531250035159840349\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___5871781006564002453:s->Values.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "cross_6828067974578293639:s->py_ndarray_12463696466920899969\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "cross_6828067974578293639:s->arange_16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_2781105897590886682:s->py_ndarray_2781105897590886682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_12463696466920899969:s->py_ndarray_12463696466920899969_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_16783941965674463102:s->py_value_8004441328793213481\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_value_5338970148915291456:s->py_value_5338970148915291456_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___1081172882011038115:s->Values.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___1081172882011038115:s->py_ndarray_2781105897590886682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__mul___14883133402278733943:s->Values.__getitem___17106626079223511235\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__mul___14883133402278733943:s->NDArray.__getitem___13531250035159840349\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___17106626079223511235:s->Values.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___17106626079223511235:s->Value.__init___0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_value_8004441328793213481:s->py_value_8004441328793213481_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___13531250035159840349:s->Values.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___13531250035159840349:s->arange_16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0:s->Value.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_12463696466920899969_0\n", - "\n", - ""np.arange(x)"\n", - "\n", - "\n", - "\n", - "\n", - "py_value_8004441328793213481_0\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_2781105897590886682_0\n", - "\n", - ""np.multiply.outer(np.arange(x), np.arange(x))"\n", - "\n", - "\n", - "\n", - "\n", - "py_value_5338970148915291456_0\n", - "\n", - ""x * x"\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0_0\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___5871781006564002453_0\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___5871781006564002453\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "cross_6828067974578293639\n", - "\n", - "cross\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_2781105897590886682\n", - "\n", - "py_ndarray\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_12463696466920899969\n", - "\n", - "py_ndarray\n", - "\n", - "\n", - "\n", - "\n", - "arange_16783941965674463102\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "py_value_5338970148915291456\n", - "\n", - "py_value\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___1081172882011038115\n", - "\n", - "NDArray.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "Value.__mul___14883133402278733943\n", - "\n", - "Value.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___17106626079223511235\n", - "\n", - "Values.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "py_value_8004441328793213481\n", - "\n", - "py_value\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___13531250035159840349\n", - "\n", - "NDArray.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_9\n", + "\n", + "\n", + "cluster_9\n", + "\n", + "\n", + "\n", + "outer_cluster_py_ndarray_12463696466920899969_0\n", + "\n", + "\n", + "cluster_py_ndarray_12463696466920899969_0\n", + "\n", + "\n", + "\n", + "outer_cluster_py_value_8004441328793213481_0\n", + "\n", + "\n", + "cluster_py_value_8004441328793213481_0\n", + "\n", + "\n", + "\n", + "outer_cluster_py_ndarray_2781105897590886682_0\n", + "\n", + "\n", + "cluster_py_ndarray_2781105897590886682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_py_value_5338970148915291456_0\n", + "\n", + "\n", + "cluster_py_value_5338970148915291456_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Values.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___0_0\n", + "\n", + "\n", + "cluster_Value.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___5871781006564002453_0:s->NDArray.__getitem___13531250035159840349\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___5871781006564002453:s->Values.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "cross_6828067974578293639:s->py_ndarray_12463696466920899969\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "cross_6828067974578293639:s->arange_16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_2781105897590886682:s->py_ndarray_2781105897590886682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_12463696466920899969:s->py_ndarray_12463696466920899969_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_16783941965674463102:s->py_value_8004441328793213481\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_value_5338970148915291456:s->py_value_5338970148915291456_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___1081172882011038115:s->Values.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___1081172882011038115:s->py_ndarray_2781105897590886682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__mul___14883133402278733943:s->Values.__getitem___17106626079223511235\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__mul___14883133402278733943:s->NDArray.__getitem___13531250035159840349\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___17106626079223511235:s->Values.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___17106626079223511235:s->Value.__init___0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_value_8004441328793213481:s->py_value_8004441328793213481_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___13531250035159840349:s->Values.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___13531250035159840349:s->arange_16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0:s->Value.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_12463696466920899969_0\n", + "\n", + ""np.arange(x)"\n", + "\n", + "\n", + "\n", + "\n", + "py_value_8004441328793213481_0\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_2781105897590886682_0\n", + "\n", + ""np.multiply.outer(np.arange(x), np.arange(x))"\n", + "\n", + "\n", + "\n", + "\n", + "py_value_5338970148915291456_0\n", + "\n", + ""x * x"\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0_0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___5871781006564002453_0\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___5871781006564002453\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "cross_6828067974578293639\n", + "\n", + "cross\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_2781105897590886682\n", + "\n", + "py_ndarray\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_12463696466920899969\n", + "\n", + "py_ndarray\n", + "\n", + "\n", + "\n", + "\n", + "arange_16783941965674463102\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "py_value_5338970148915291456\n", + "\n", + "py_value\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___1081172882011038115\n", + "\n", + "NDArray.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "Value.__mul___14883133402278733943\n", + "\n", + "Value.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___17106626079223511235\n", + "\n", + "Values.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "py_value_8004441328793213481\n", + "\n", + "py_value\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___13531250035159840349\n", + "\n", + "NDArray.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "" ], - "source": [ - "from IPython.display import SVG, display\n", - "\n", - "with open(\"big_graph.svg\") as f:\n", - " display(SVG(f.read()))" - ] - }, - { - "cell_type": "markdown", - "id": "d4ef7a6c-5fca-46ff-89d6-ab7e659f1c82", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "_Saul Shanabrook - July 20, 2023_\n" - ] - }, - { - "cell_type": "markdown", - "id": "72e644b5-c987-45de-87d7-ee9da885b85f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Open Source Data Science Ecosystem in Python\n", - "\n", - "> The term “ecosystem” is often used to describe the modern open-source scientific software. In biology, the term “ecosystem” is defined as a biological community of interacting organisms and their physical environment. Modern open-source scientific software development occurs in a similarly interconnected and interoperable fashion.\n", - "\n", - "from [Jupyter Meets the Earth: Ecosystem](https://jupytearth.org/jupyter-resources/introduction/ecosystem.html)\n", - "\n", - "![](https://jupytearth.org/_images/python-stack.png)\n" - ] - }, - { - "cell_type": "markdown", - "id": "90785f75-e933-469f-b585-127f0e4fc584", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "### Aims\n", - "\n", - "- How can the tools we build foster greater **resiliancy, collaboration, and interdependence** in this ecosystem?
\n", - "- How can they help it **stay flexible enough to adapt to the changing computational landscape** to empower users and authors?\n", - "\n", - "### What role could `egglog` play?\n", - "\n", - "- Bring the programming languages community closer to this space, providing theoretical frameworks for thinking about composition and language.\n", - "- Constrained type system could support decentralized interopability and composition between data science libraries.\n" - ] - }, - { - "cell_type": "markdown", - "id": "0b49d9a5-ef01-4f2b-a6f7-1bc1e5087201", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "### Other Python EGraph Libraries\n", - "\n", - "- [`riswords/quiche`](https://github.com/riswords/quiche): Optimizing Python ASTs\n", - "- [`egraphs-good/snake-egg`](https://github.com/egraphs-good/snake-egg): Generic bindings for `egg`, can bring any Python objects as expressions.\n", - "- [EGraph library added to `ibis`](https://github.com/ibis-project/ibis/pull/5781): Conversions between dataframe syntax and SQL dialects\n" - ] - }, - { - "cell_type": "markdown", - "id": "c4c37446-3426-4b57-a402-2a234b54d930", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "TODO: Put this first, Say it's for library authors\n", - "\n", - "Semantics of python and egglog\n" + "text/plain": [ + "" ] - }, - { - "cell_type": "markdown", - "id": "eadf7129-68f3-4fcc-87a4-57e064f66fc8", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Started with `snake-egg`\n", - "- Didn't want to re-invent the wheel, stay abreast of recent developments and research\n", - "- Second piece that interests me\n", - " - Unlike `egg` there are some builtin sorts, and can build user defined sorts on top of those\n", - " - No host language conditions or data structures\n", - " - Helps with optimization, more constrained\n", - " - -> De-centers algorithms based on value, move to based on type. Everything becomes an interface.\n", - " - Social dynamics, goal is ability to inovate and experiment, while still supporting existing use cases\n", - " - New dataframe library comes out, supporting custom hardware. How dow we use it without rewriting code?\n", - " - How do we have healthy ecosystem within these tools? Power\n", - " - If it's too hard, encourages centralized monopolistic actors to step in provide one stop shop solutions for users.\n", - " - Active problem in the community, with things like trying to standardize on interop.\n", - " - Before getting too abstract, let's go to an example\n" - ] - }, - { - "cell_type": "markdown", - "id": "ba2b7093-0927-45ff-99ca-d58c31c9f5c6", - "metadata": { - "editable": true, - "jp-MarkdownHeadingCollapsed": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "## What is an e-graph?\n" - ] - }, - { - "cell_type": "markdown", - "id": "319f9e5c-7165-4844-b957-a77ce807f98d", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "> E-graphs are these super wonderful data structures for managing equality and equivalence information. They are traditionally used inside of constraint solvers and automated theorem provers to implement **congruence closure**, an efficient algorithm for equational reasoning---but they can also be used to implement **rewrite systems**.\n", - ">\n", - "> [Talia Ringer - \"Proof Automation\" course](https://dependenttyp.es/classes/readings/17-egraphs.html)\n" - ] - }, - { - "cell_type": "markdown", - "id": "34ac3ee6-4053-49d7-b9ee-0adafd3dabb6", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Come from automated theorum proving world\n", - "- Something congruence, which is like how triangles are similar but not equal,\n", - "- Can be used for term rewriting\n" - ] - }, - { - "cell_type": "markdown", - "id": "d4a57fd4-1253-47fb-82f2-476c80fdddab", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "> In abstract algebra, a congruence relation (or simply congruence) is an equivalence relation on an algebraic structure (such as a group, ring, or vector space) that is compatible with the structure in the sense that **algebraic operations done with equivalent elements will yield equivalent elements**.\n", - ">\n", - "> [Wikipedia - Congruence relation](https://en.wikipedia.org/wiki/Congruence_relation)\n" - ] - }, - { - "cell_type": "markdown", - "id": "fa5cbdaa-d89e-4602-ab36-ce0608ce3cc7", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- doing one thing on a set will be the same as doing it on another\n" - ] - }, - { - "cell_type": "markdown", - "id": "89509032-cc46-4489-8532-d60f9b455db7", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "### Congruence Closure\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "5d4831fb-6c07-454b-9767-e1aeb452eeb2", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "from __future__ import annotations" - ] - }, + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from IPython.display import SVG, display\n", + "\n", + "with open(\"big_graph.svg\") as f:\n", + " display(SVG(f.read()))" + ] + }, + { + "cell_type": "markdown", + "id": "d4ef7a6c-5fca-46ff-89d6-ab7e659f1c82", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "_Saul Shanabrook - July 20, 2023_\n" + ] + }, + { + "cell_type": "markdown", + "id": "72e644b5-c987-45de-87d7-ee9da885b85f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## Open Source Data Science Ecosystem in Python\n", + "\n", + "> The term “ecosystem” is often used to describe the modern open-source scientific software. In biology, the term “ecosystem” is defined as a biological community of interacting organisms and their physical environment. Modern open-source scientific software development occurs in a similarly interconnected and interoperable fashion.\n", + "\n", + "from [Jupyter Meets the Earth: Ecosystem](https://jupytearth.org/jupyter-resources/introduction/ecosystem.html)\n", + "\n", + "![](https://jupytearth.org/_images/python-stack.png)\n" + ] + }, + { + "cell_type": "markdown", + "id": "90785f75-e933-469f-b585-127f0e4fc584", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "source": [ + "### Aims\n", + "\n", + "- How can the tools we build foster greater **resiliancy, collaboration, and interdependence** in this ecosystem?
\n", + "- How can they help it **stay flexible enough to adapt to the changing computational landscape** to empower users and authors?\n", + "\n", + "### What role could `egglog` play?\n", + "\n", + "- Bring the programming languages community closer to this space, providing theoretical frameworks for thinking about composition and language.\n", + "- Constrained type system could support decentralized interopability and composition between data science libraries.\n" + ] + }, + { + "cell_type": "markdown", + "id": "0b49d9a5-ef01-4f2b-a6f7-1bc1e5087201", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "source": [ + "### Other Python EGraph Libraries\n", + "\n", + "- [`riswords/quiche`](https://github.com/riswords/quiche): Optimizing Python ASTs\n", + "- [`egraphs-good/snake-egg`](https://github.com/egraphs-good/snake-egg): Generic bindings for `egg`, can bring any Python objects as expressions.\n", + "- [EGraph library added to `ibis`](https://github.com/ibis-project/ibis/pull/5781): Conversions between dataframe syntax and SQL dialects\n" + ] + }, + { + "cell_type": "markdown", + "id": "c4c37446-3426-4b57-a402-2a234b54d930", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "source": [ + "TODO: Put this first, Say it's for library authors\n", + "\n", + "Semantics of python and egglog\n" + ] + }, + { + "cell_type": "markdown", + "id": "eadf7129-68f3-4fcc-87a4-57e064f66fc8", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Started with `snake-egg`\n", + "- Didn't want to re-invent the wheel, stay abreast of recent developments and research\n", + "- Second piece that interests me\n", + " - Unlike `egg` there are some builtin sorts, and can build user defined sorts on top of those\n", + " - No host language conditions or data structures\n", + " - Helps with optimization, more constrained\n", + " - -> De-centers algorithms based on value, move to based on type. Everything becomes an interface.\n", + " - Social dynamics, goal is ability to inovate and experiment, while still supporting existing use cases\n", + " - New dataframe library comes out, supporting custom hardware. How dow we use it without rewriting code?\n", + " - How do we have healthy ecosystem within these tools? Power\n", + " - If it's too hard, encourages centralized monopolistic actors to step in provide one stop shop solutions for users.\n", + " - Active problem in the community, with things like trying to standardize on interop.\n", + " - Before getting too abstract, let's go to an example\n" + ] + }, + { + "cell_type": "markdown", + "id": "ba2b7093-0927-45ff-99ca-d58c31c9f5c6", + "metadata": { + "editable": true, + "jp-MarkdownHeadingCollapsed": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "source": [ + "## What is an e-graph?\n" + ] + }, + { + "cell_type": "markdown", + "id": "319f9e5c-7165-4844-b957-a77ce807f98d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "> E-graphs are these super wonderful data structures for managing equality and equivalence information. They are traditionally used inside of constraint solvers and automated theorem provers to implement **congruence closure**, an efficient algorithm for equational reasoning---but they can also be used to implement **rewrite systems**.\n", + ">\n", + "> [Talia Ringer - \"Proof Automation\" course](https://dependenttyp.es/classes/readings/17-egraphs.html)\n" + ] + }, + { + "cell_type": "markdown", + "id": "34ac3ee6-4053-49d7-b9ee-0adafd3dabb6", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Come from automated theorum proving world\n", + "- Something congruence, which is like how triangles are similar but not equal,\n", + "- Can be used for term rewriting\n" + ] + }, + { + "cell_type": "markdown", + "id": "d4a57fd4-1253-47fb-82f2-476c80fdddab", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "> In abstract algebra, a congruence relation (or simply congruence) is an equivalence relation on an algebraic structure (such as a group, ring, or vector space) that is compatible with the structure in the sense that **algebraic operations done with equivalent elements will yield equivalent elements**.\n", + ">\n", + "> [Wikipedia - Congruence relation](https://en.wikipedia.org/wiki/Congruence_relation)\n" + ] + }, + { + "cell_type": "markdown", + "id": "fa5cbdaa-d89e-4602-ab36-ce0608ce3cc7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- doing one thing on a set will be the same as doing it on another\n" + ] + }, + { + "cell_type": "markdown", + "id": "89509032-cc46-4489-8532-d60f9b455db7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "source": [ + "### Congruence Closure\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "5d4831fb-6c07-454b-9767-e1aeb452eeb2", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "from __future__ import annotations" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "51ab67c6-c099-4a66-9344-3c4884ac33bf", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 3, - "id": "51ab67c6-c099-4a66-9344-3c4884ac33bf", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->b_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_17615343019692007359:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_17615343019692007359:s->c_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_0\n", - "\n", - "\n", - "a\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "b_0\n", - "\n", - "\n", - "b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "c_0\n", - "\n", - "\n", - "c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_b_0\n", - "\n", - "\n", - "a_b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_17615343019692007359\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_c_0\n", - "\n", - "\n", - "a_c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->b_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_17615343019692007359:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_17615343019692007359:s->c_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_0\n", - "\n", - "\n", - "a\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "b_0\n", - "\n", - "\n", - "b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "c_0\n", - "\n", - "\n", - "c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_b_0\n", - "\n", - "\n", - "a_b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_17615343019692007359\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_c_0\n", - "\n", - "\n", - "a_c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'operation': FunctionDecl(arg_types=(TypeRefWithVars(name='Structure', args=()), TypeRefWithVars(name='Structure', args=())), arg_names=('l', 'r'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Structure', args=()), var_arg_type=None)}, _classes={'Structure': ClassDecl(methods={}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={'a': JustTypeRef(name='Structure', args=()), 'b': JustTypeRef(name='Structure', args=()), 'c': JustTypeRef(name='Structure', args=())}, _egg_fn_to_callable_refs=defaultdict(, {'!=': {MethodRef(class_name='Structure', method_name='__ne__')}, 'a': {ConstantRef(name='a')}, 'b': {ConstantRef(name='b')}, 'c': {ConstantRef(name='c')}, 'operation': {FunctionRef(name='operation')}}), _callable_ref_to_egg_fn={MethodRef(class_name='Structure', method_name='__ne__'): '!=', ConstantRef(name='a'): 'a', ConstantRef(name='b'): 'b', ConstantRef(name='c'): 'c', FunctionRef(name='operation'): 'operation'}, _egg_sort_to_type_ref={'Structure': JustTypeRef(name='Structure', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Structure', args=()): 'Structure'})))" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->b_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_17615343019692007359:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_17615343019692007359:s->c_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_0\n", + "\n", + "\n", + "a\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "b_0\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "c_0\n", + "\n", + "\n", + "c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_b_0\n", + "\n", + "\n", + "a_b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_17615343019692007359\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_c_0\n", + "\n", + "\n", + "a_c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->b_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_17615343019692007359:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_17615343019692007359:s->c_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_0\n", + "\n", + "\n", + "a\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "b_0\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "c_0\n", + "\n", + "\n", + "c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_b_0\n", + "\n", + "\n", + "a_b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_17615343019692007359\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_c_0\n", + "\n", + "\n", + "a_c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "from egglog import *\n", - "\n", - "egraph = EGraph()\n", - "\n", - "\n", - "@egraph.class_\n", - "class Structure(Expr):\n", - " ...\n", - "\n", - "\n", - "a = egraph.constant(\"a\", Structure)\n", - "b = egraph.constant(\"b\", Structure)\n", - "c = egraph.constant(\"c\", Structure)\n", - "\n", - "\n", - "@egraph.function\n", - "def operation(l: Structure, r: Structure) -> Structure:\n", - " ...\n", - "\n", - "\n", - "a_b = egraph.let(\"a_b\", operation(a, b))\n", - "a_c = egraph.let(\"a_c\", operation(a, c))\n", - "\n", - "egraph" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'operation': FunctionDecl(arg_types=(TypeRefWithVars(name='Structure', args=()), TypeRefWithVars(name='Structure', args=())), arg_names=('l', 'r'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Structure', args=()), var_arg_type=None)}, _classes={'Structure': ClassDecl(methods={}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={'a': JustTypeRef(name='Structure', args=()), 'b': JustTypeRef(name='Structure', args=()), 'c': JustTypeRef(name='Structure', args=())}, _egg_fn_to_callable_refs=defaultdict(, {'!=': {MethodRef(class_name='Structure', method_name='__ne__')}, 'a': {ConstantRef(name='a')}, 'b': {ConstantRef(name='b')}, 'c': {ConstantRef(name='c')}, 'operation': {FunctionRef(name='operation')}}), _callable_ref_to_egg_fn={MethodRef(class_name='Structure', method_name='__ne__'): '!=', ConstantRef(name='a'): 'a', ConstantRef(name='b'): 'b', ConstantRef(name='c'): 'c', FunctionRef(name='operation'): 'operation'}, _egg_sort_to_type_ref={'Structure': JustTypeRef(name='Structure', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Structure', args=()): 'Structure'})))" ] - }, + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from egglog import *\n", + "\n", + "egraph = EGraph()\n", + "\n", + "\n", + "@egraph.class_\n", + "class Structure(Expr): ...\n", + "\n", + "\n", + "a = egraph.constant(\"a\", Structure)\n", + "b = egraph.constant(\"b\", Structure)\n", + "c = egraph.constant(\"c\", Structure)\n", + "\n", + "\n", + "@egraph.function\n", + "def operation(l: Structure, r: Structure) -> Structure: ...\n", + "\n", + "\n", + "a_b = egraph.let(\"a_b\", operation(a, b))\n", + "a_c = egraph.let(\"a_c\", operation(a, c))\n", + "\n", + "egraph" + ] + }, + { + "cell_type": "markdown", + "id": "9ffbef64-c611-4796-a085-09e63aab3b02", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Define a structure, define an operation on that structure\n", + "- Define two elements\n", + "- Are they equal?\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "80129d3e-c785-407e-a761-f9b767027f7a", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "9ffbef64-c611-4796-a085-09e63aab3b02", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Define a structure, define an operation on that structure\n", - "- Define two elements\n", - "- Are they equal?\n" - ] - }, + "ename": "EggSmolError", + "evalue": "Check failed: \n(= a_b a_c)", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mEggSmolError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43megraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcheck\u001b[49m\u001b[43m(\u001b[49m\u001b[43meq\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma_b\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma_c\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:721\u001b[0m, in \u001b[0;36mEGraph.check\u001b[0;34m(self, *facts)\u001b[0m\n\u001b[1;32m 717\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcheck\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39mfacts: FactLike) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 718\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 719\u001b[0m \u001b[38;5;124;03m Check if a fact is true in the egraph.\u001b[39;00m\n\u001b[1;32m 720\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 721\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_process_commands\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_facts_to_check\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfacts\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:634\u001b[0m, in \u001b[0;36mEGraph._process_commands\u001b[0;34m(self, commands)\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_process_commands\u001b[39m(\u001b[38;5;28mself\u001b[39m, commands: Iterable[bindings\u001b[38;5;241m.\u001b[39m_Command]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 634\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_egraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_program\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcommands\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mEggSmolError\u001b[0m: Check failed: \n(= a_b a_c)" + ] + } + ], + "source": [ + "egraph.check(eq(a_b).to(a_c))" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e7b23122-0659-4cb2-b8cc-68bb7e71575a", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 4, - "id": "80129d3e-c785-407e-a761-f9b767027f7a", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "ename": "EggSmolError", - "evalue": "Check failed: \n(= a_b a_c)", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mEggSmolError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[4], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43megraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcheck\u001b[49m\u001b[43m(\u001b[49m\u001b[43meq\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma_b\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma_c\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:721\u001b[0m, in \u001b[0;36mEGraph.check\u001b[0;34m(self, *facts)\u001b[0m\n\u001b[1;32m 717\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcheck\u001b[39m(\u001b[38;5;28mself\u001b[39m, \u001b[38;5;241m*\u001b[39mfacts: FactLike) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 718\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"\u001b[39;00m\n\u001b[1;32m 719\u001b[0m \u001b[38;5;124;03m Check if a fact is true in the egraph.\u001b[39;00m\n\u001b[1;32m 720\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 721\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_process_commands\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_facts_to_check\u001b[49m\u001b[43m(\u001b[49m\u001b[43mfacts\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:634\u001b[0m, in \u001b[0;36mEGraph._process_commands\u001b[0;34m(self, commands)\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_process_commands\u001b[39m(\u001b[38;5;28mself\u001b[39m, commands: Iterable[bindings\u001b[38;5;241m.\u001b[39m_Command]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 634\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_egraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_program\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcommands\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[0;31mEggSmolError\u001b[0m: Check failed: \n(= a_b a_c)" - ] - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->b_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_0\n", + "\n", + "\n", + "a\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_b_0\n", + "\n", + "\n", + "a_b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_c_0\n", + "\n", + "\n", + "a_c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "c_0\n", + "\n", + "\n", + "c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "b_0\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph.check(eq(a_b).to(a_c))" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "e7b23122-0659-4cb2-b8cc-68bb7e71575a", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->b_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_0\n", - "\n", - "\n", - "a\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_b_0\n", - "\n", - "\n", - "a_b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_c_0\n", - "\n", - "\n", - "a_c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "c_0\n", - "\n", - "\n", - "c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "b_0\n", - "\n", - "\n", - "b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->b_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_0\n", - "\n", - "\n", - "a\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_b_0\n", - "\n", - "\n", - "a_b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_c_0\n", - "\n", - "\n", - "a_c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "c_0\n", - "\n", - "\n", - "c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "b_0\n", - "\n", - "\n", - "b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'operation': FunctionDecl(arg_types=(TypeRefWithVars(name='Structure', args=()), TypeRefWithVars(name='Structure', args=())), arg_names=('l', 'r'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Structure', args=()), var_arg_type=None)}, _classes={'Structure': ClassDecl(methods={}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={'a': JustTypeRef(name='Structure', args=()), 'b': JustTypeRef(name='Structure', args=()), 'c': JustTypeRef(name='Structure', args=())}, _egg_fn_to_callable_refs=defaultdict(, {'!=': {MethodRef(class_name='Structure', method_name='__ne__')}, 'a': {ConstantRef(name='a')}, 'b': {ConstantRef(name='b')}, 'c': {ConstantRef(name='c')}, 'operation': {FunctionRef(name='operation')}}), _callable_ref_to_egg_fn={MethodRef(class_name='Structure', method_name='__ne__'): '!=', ConstantRef(name='a'): 'a', ConstantRef(name='b'): 'b', ConstantRef(name='c'): 'c', FunctionRef(name='operation'): 'operation'}, _egg_sort_to_type_ref={'Structure': JustTypeRef(name='Structure', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Structure', args=()): 'Structure'})))" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->b_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_0\n", + "\n", + "\n", + "a\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_b_0\n", + "\n", + "\n", + "a_b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_c_0\n", + "\n", + "\n", + "a_c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "c_0\n", + "\n", + "\n", + "c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "b_0\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph.register(union(b).with_(c))\n", - "egraph.run(1)\n", - "egraph.check(eq(a_b).to(a_c))\n", - "egraph" - ] - }, - { - "cell_type": "markdown", - "id": "09365349-391d-46d8-b6aa-eb09d1e91626", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "We just used `egglog` to\n", - "\n", - "- Define a structure\n", - "- Define some operation on that structure\n", - "- See it give us a congruence relation on that structure\n", - " - \"algebraic operations done with equivalent elements will yield equivalent elements\"\n", - " - We call a set of equivalent elements an **\"e-class\"** i.e. {a} or {b, c}\n", - " - We only store pointers to other e-classes, not elements\n" - ] - }, - { - "cell_type": "markdown", - "id": "69ebee03-5dd6-4985-83ee-fbabbf3c2a91", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Combining elements... so that operations done on two elements of the same\n" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'operation': FunctionDecl(arg_types=(TypeRefWithVars(name='Structure', args=()), TypeRefWithVars(name='Structure', args=())), arg_names=('l', 'r'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Structure', args=()), var_arg_type=None)}, _classes={'Structure': ClassDecl(methods={}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={'a': JustTypeRef(name='Structure', args=()), 'b': JustTypeRef(name='Structure', args=()), 'c': JustTypeRef(name='Structure', args=())}, _egg_fn_to_callable_refs=defaultdict(, {'!=': {MethodRef(class_name='Structure', method_name='__ne__')}, 'a': {ConstantRef(name='a')}, 'b': {ConstantRef(name='b')}, 'c': {ConstantRef(name='c')}, 'operation': {FunctionRef(name='operation')}}), _callable_ref_to_egg_fn={MethodRef(class_name='Structure', method_name='__ne__'): '!=', ConstantRef(name='a'): 'a', ConstantRef(name='b'): 'b', ConstantRef(name='c'): 'c', FunctionRef(name='operation'): 'operation'}, _egg_sort_to_type_ref={'Structure': JustTypeRef(name='Structure', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Structure', args=()): 'Structure'})))" ] - }, - { - "cell_type": "markdown", - "id": "f2ddca09-d7bd-44be-807f-dba33a154ef8", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "### \"Rewrite systems\"?\n" - ] - }, + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.register(union(b).with_(c))\n", + "egraph.run(1)\n", + "egraph.check(eq(a_b).to(a_c))\n", + "egraph" + ] + }, + { + "cell_type": "markdown", + "id": "09365349-391d-46d8-b6aa-eb09d1e91626", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "We just used `egglog` to\n", + "\n", + "- Define a structure\n", + "- Define some operation on that structure\n", + "- See it give us a congruence relation on that structure\n", + " - \"algebraic operations done with equivalent elements will yield equivalent elements\"\n", + " - We call a set of equivalent elements an **\"e-class\"** i.e. {a} or {b, c}\n", + " - We only store pointers to other e-classes, not elements\n" + ] + }, + { + "cell_type": "markdown", + "id": "69ebee03-5dd6-4985-83ee-fbabbf3c2a91", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Combining elements... so that operations done on two elements of the same\n" + ] + }, + { + "cell_type": "markdown", + "id": "f2ddca09-d7bd-44be-807f-dba33a154ef8", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "source": [ + "### \"Rewrite systems\"?\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "0244d1bb-3925-431e-9afc-18e9df655e81", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 6, - "id": "0244d1bb-3925-431e-9afc-18e9df655e81", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->b_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_956286968014291186:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_956286968014291186:s->c_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_0\n", - "\n", - "\n", - "a\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_956286968014291186\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_b_0\n", - "\n", - "\n", - "a_b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_c_0\n", - "\n", - "\n", - "a_c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "c_0\n", - "\n", - "\n", - "c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "b_0\n", - "\n", - "\n", - "b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453:s->b_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_956286968014291186:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_956286968014291186:s->c_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_0\n", - "\n", - "\n", - "a\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_5871781006564002453\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_956286968014291186\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_b_0\n", - "\n", - "\n", - "a_b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_c_0\n", - "\n", - "\n", - "a_c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "c_0\n", - "\n", - "\n", - "c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "b_0\n", - "\n", - "\n", - "b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'operation': FunctionDecl(arg_types=(TypeRefWithVars(name='Structure', args=()), TypeRefWithVars(name='Structure', args=())), arg_names=('l', 'r'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Structure', args=()), var_arg_type=None)}, _classes={'Structure': ClassDecl(methods={}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={'a': JustTypeRef(name='Structure', args=()), 'b': JustTypeRef(name='Structure', args=()), 'c': JustTypeRef(name='Structure', args=())}, _egg_fn_to_callable_refs=defaultdict(, {'!=': {MethodRef(class_name='Structure', method_name='__ne__')}, 'a': {ConstantRef(name='a')}, 'b': {ConstantRef(name='b')}, 'c': {ConstantRef(name='c')}, 'operation': {FunctionRef(name='operation')}}), _callable_ref_to_egg_fn={MethodRef(class_name='Structure', method_name='__ne__'): '!=', ConstantRef(name='a'): 'a', ConstantRef(name='b'): 'b', ConstantRef(name='c'): 'c', FunctionRef(name='operation'): 'operation'}, _egg_sort_to_type_ref={'Structure': JustTypeRef(name='Structure', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Structure', args=()): 'Structure'})))" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->b_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_956286968014291186:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_956286968014291186:s->c_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_0\n", + "\n", + "\n", + "a\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_956286968014291186\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_b_0\n", + "\n", + "\n", + "a_b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_c_0\n", + "\n", + "\n", + "a_c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "c_0\n", + "\n", + "\n", + "c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "b_0\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453:s->b_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_956286968014291186:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_956286968014291186:s->c_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_0\n", + "\n", + "\n", + "a\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_5871781006564002453\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_956286968014291186\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_b_0\n", + "\n", + "\n", + "a_b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_c_0\n", + "\n", + "\n", + "a_c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "c_0\n", + "\n", + "\n", + "c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "b_0\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "@egraph.register\n", - "def _operation_commutative(left: Structure, right: Structure):\n", - " yield rewrite(operation(left, right)).to(operation(right, left))\n", - "\n", - "\n", - "egraph.run(run().saturate())\n", - "egraph.check(eq(operation(a, b)).to(operation(b, a)))\n", - "egraph" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'operation': FunctionDecl(arg_types=(TypeRefWithVars(name='Structure', args=()), TypeRefWithVars(name='Structure', args=())), arg_names=('l', 'r'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Structure', args=()), var_arg_type=None)}, _classes={'Structure': ClassDecl(methods={}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={'a': JustTypeRef(name='Structure', args=()), 'b': JustTypeRef(name='Structure', args=()), 'c': JustTypeRef(name='Structure', args=())}, _egg_fn_to_callable_refs=defaultdict(, {'!=': {MethodRef(class_name='Structure', method_name='__ne__')}, 'a': {ConstantRef(name='a')}, 'b': {ConstantRef(name='b')}, 'c': {ConstantRef(name='c')}, 'operation': {FunctionRef(name='operation')}}), _callable_ref_to_egg_fn={MethodRef(class_name='Structure', method_name='__ne__'): '!=', ConstantRef(name='a'): 'a', ConstantRef(name='b'): 'b', ConstantRef(name='c'): 'c', FunctionRef(name='operation'): 'operation'}, _egg_sort_to_type_ref={'Structure': JustTypeRef(name='Structure', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Structure', args=()): 'Structure'})))" ] - }, + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@egraph.register\n", + "def _operation_commutative(left: Structure, right: Structure):\n", + " yield rewrite(operation(left, right)).to(operation(right, left))\n", + "\n", + "\n", + "egraph.run(run().saturate())\n", + "egraph.check(eq(operation(a, b)).to(operation(b, a)))\n", + "egraph" + ] + }, + { + "cell_type": "markdown", + "id": "b0cb9d48-f0c5-4e19-b74d-a199a229f586", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "`egglog` can also be used for rewrite system:\n", + "\n", + "- Define rules which will be matched on the e-graph\n", + "- The results will be added to the e-graph\n", + "- Can keep runnning these rules until the e-graph is \"saturated\"\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "ff761614-48c3-4fb0-b07a-3a87eada032a", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "b0cb9d48-f0c5-4e19-b74d-a199a229f586", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "`egglog` can also be used for rewrite system:\n", - "\n", - "- Define rules which will be matched on the e-graph\n", - "- The results will be added to the e-graph\n", - "- Can keep runnning these rules until the e-graph is \"saturated\"\n" + "data": { + "text/plain": [ + "b" ] - }, + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@egraph.register\n", + "def _operation_identity(s: Structure):\n", + " yield rewrite(operation(c, s)).to(c)\n", + "\n", + "\n", + "egraph.run(run().saturate())\n", + "egraph.extract(operation(c, a))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "e6cf516e-9994-4edc-bd35-9143d2cb1817", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [ + "remove-input" + ] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 7, - "id": "ff761614-48c3-4fb0-b07a-3a87eada032a", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "b" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "\n", + "operation_1912573936028582372:s->c_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_1912573936028582372:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_11743562013128004906:s->a_b_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_11743562013128004906:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_c_0\n", + "\n", + "\n", + "a_c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "b_0\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_1912573936028582372\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_11743562013128004906\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_b_0\n", + "\n", + "\n", + "a_b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "c_0\n", + "\n", + "\n", + "c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_0\n", + "\n", + "\n", + "a\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "@egraph.register\n", - "def _operation_identity(s: Structure):\n", - " yield rewrite(operation(c, s)).to(c)\n", - "\n", - "\n", - "egraph.run(run().saturate())\n", - "egraph.extract(operation(c, a))" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "e6cf516e-9994-4edc-bd35-9143d2cb1817", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [ - "remove-input" - ] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "\n", - "operation_1912573936028582372:s->c_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_1912573936028582372:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_11743562013128004906:s->a_b_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_11743562013128004906:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_c_0\n", - "\n", - "\n", - "a_c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "b_0\n", - "\n", - "\n", - "b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_1912573936028582372\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_11743562013128004906\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_b_0\n", - "\n", - "\n", - "a_b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "c_0\n", - "\n", - "\n", - "c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_0\n", - "\n", - "\n", - "a\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "\n", - "operation_1912573936028582372:s->c_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_1912573936028582372:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_11743562013128004906:s->a_b_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_11743562013128004906:s->a_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_c_0\n", - "\n", - "\n", - "a_c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "b_0\n", - "\n", - "\n", - "b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_1912573936028582372\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "operation_11743562013128004906\n", - "\n", - "\n", - "operation\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_b_0\n", - "\n", - "\n", - "a_b\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "c_0\n", - "\n", - "\n", - "c\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "a_0\n", - "\n", - "\n", - "a\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'operation': FunctionDecl(arg_types=(TypeRefWithVars(name='Structure', args=()), TypeRefWithVars(name='Structure', args=())), arg_names=('l', 'r'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Structure', args=()), var_arg_type=None)}, _classes={'Structure': ClassDecl(methods={}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={'a': JustTypeRef(name='Structure', args=()), 'b': JustTypeRef(name='Structure', args=()), 'c': JustTypeRef(name='Structure', args=())}, _egg_fn_to_callable_refs=defaultdict(, {'!=': {MethodRef(class_name='Structure', method_name='__ne__')}, 'a': {ConstantRef(name='a')}, 'b': {ConstantRef(name='b')}, 'c': {ConstantRef(name='c')}, 'operation': {FunctionRef(name='operation')}}), _callable_ref_to_egg_fn={MethodRef(class_name='Structure', method_name='__ne__'): '!=', ConstantRef(name='a'): 'a', ConstantRef(name='b'): 'b', ConstantRef(name='c'): 'c', FunctionRef(name='operation'): 'operation'}, _egg_sort_to_type_ref={'Structure': JustTypeRef(name='Structure', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Structure', args=()): 'Structure'})))" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "\n", + "operation_1912573936028582372:s->c_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_1912573936028582372:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_11743562013128004906:s->a_b_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_11743562013128004906:s->a_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_c_0\n", + "\n", + "\n", + "a_c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "b_0\n", + "\n", + "\n", + "b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_1912573936028582372\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "operation_11743562013128004906\n", + "\n", + "\n", + "operation\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_b_0\n", + "\n", + "\n", + "a_b\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "c_0\n", + "\n", + "\n", + "c\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "a_0\n", + "\n", + "\n", + "a\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph" - ] - }, - { - "cell_type": "markdown", - "id": "c2b26c2c-c82b-49aa-9957-09b415af24e6", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "- Define `c` as the identity for this operation\n", - "- \"extract\" an expression to find lowest cost equivalent expression\n" - ] - }, - { - "cell_type": "markdown", - "id": "4867f83d-c51c-4860-8c4d-65094404f503", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "What are e-graphs?\n", - "\n", - "- Data structure to hold \"congruence closure\" i.e. sets of equivalent items\n", - "- Can implement term rewriting system on them\n", - " - Order of rewrites don't matter b/c application only add information\n", - " - Extract \"best\" expression from e-graph after applying rules\n" - ] - }, - { - "cell_type": "markdown", - "id": "0d6a04c7-4cc5-4375-b95c-038960ed231e", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "## What is `egglog`?\n" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'operation': FunctionDecl(arg_types=(TypeRefWithVars(name='Structure', args=()), TypeRefWithVars(name='Structure', args=())), arg_names=('l', 'r'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Structure', args=()), var_arg_type=None)}, _classes={'Structure': ClassDecl(methods={}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={'a': JustTypeRef(name='Structure', args=()), 'b': JustTypeRef(name='Structure', args=()), 'c': JustTypeRef(name='Structure', args=())}, _egg_fn_to_callable_refs=defaultdict(, {'!=': {MethodRef(class_name='Structure', method_name='__ne__')}, 'a': {ConstantRef(name='a')}, 'b': {ConstantRef(name='b')}, 'c': {ConstantRef(name='c')}, 'operation': {FunctionRef(name='operation')}}), _callable_ref_to_egg_fn={MethodRef(class_name='Structure', method_name='__ne__'): '!=', ConstantRef(name='a'): 'a', ConstantRef(name='b'): 'b', ConstantRef(name='c'): 'c', FunctionRef(name='operation'): 'operation'}, _egg_sort_to_type_ref={'Structure': JustTypeRef(name='Structure', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Structure', args=()): 'Structure'})))" ] - }, - { - "cell_type": "markdown", - "id": "03527e0e-448e-4b57-8532-02a945e7f1d0", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "![](egg.png)\n" - ] - }, - { - "cell_type": "markdown", - "id": "54f61359-111b-45f8-b7b2-e54d21aa2ccd", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Will show how some examples translate\n" - ] - }, - { - "cell_type": "markdown", - "id": "673a0c32-2b21-431e-b5fc-6d8b29abf6a5", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Sorts, expressions, and functions\n" - ] - }, + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph" + ] + }, + { + "cell_type": "markdown", + "id": "c2b26c2c-c82b-49aa-9957-09b415af24e6", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "- Define `c` as the identity for this operation\n", + "- \"extract\" an expression to find lowest cost equivalent expression\n" + ] + }, + { + "cell_type": "markdown", + "id": "4867f83d-c51c-4860-8c4d-65094404f503", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "What are e-graphs?\n", + "\n", + "- Data structure to hold \"congruence closure\" i.e. sets of equivalent items\n", + "- Can implement term rewriting system on them\n", + " - Order of rewrites don't matter b/c application only add information\n", + " - Extract \"best\" expression from e-graph after applying rules\n" + ] + }, + { + "cell_type": "markdown", + "id": "0d6a04c7-4cc5-4375-b95c-038960ed231e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "source": [ + "## What is `egglog`?\n" + ] + }, + { + "cell_type": "markdown", + "id": "03527e0e-448e-4b57-8532-02a945e7f1d0", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "![](egg.png)\n" + ] + }, + { + "cell_type": "markdown", + "id": "54f61359-111b-45f8-b7b2-e54d21aa2ccd", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Will show how some examples translate\n" + ] + }, + { + "cell_type": "markdown", + "id": "673a0c32-2b21-431e-b5fc-6d8b29abf6a5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### Sorts, expressions, and functions\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "33d34134-78c9-472b-b364-479c3aca3b23", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 9, - "id": "33d34134-78c9-472b-b364-479c3aca3b23", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Var_7848520443469635519_0\n", - "\n", - "\n", - "cluster_Var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896:s->Var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896:s->Num_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453:s->Var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_13095445380246898500:s->Mul_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_13095445380246898500:s->Num_16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906:s->Num_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_7848520443469635519:s->Var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359:s->Add_7659469028595837896\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359:s->Num_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102:s->Num_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_7848520443469635519_0\n", - "\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102_0\n", - "\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896\n", - "\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453\n", - "\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_13095445380246898500\n", - "\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906\n", - "\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_7848520443469635519\n", - "\n", - "\n", - "Var\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359\n", - "\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359\n", - "\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102\n", - "\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Var_7848520443469635519_0\n", + "\n", + "\n", + "cluster_Var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896:s->Var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896:s->Num_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453:s->Var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_13095445380246898500:s->Mul_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_13095445380246898500:s->Num_16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906:s->Num_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_7848520443469635519:s->Var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359:s->Add_7659469028595837896\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359:s->Num_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102:s->Num_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_7848520443469635519_0\n", + "\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102_0\n", + "\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896\n", + "\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453\n", + "\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_13095445380246898500\n", + "\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906\n", + "\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_7848520443469635519\n", + "\n", + "\n", + "Var\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359\n", + "\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359\n", + "\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102\n", + "\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "%%egglog graph\n", - "(datatype Math\n", - " (Num i64)\n", - " (Var String)\n", - " (Add Math Math)\n", - " (Mul Math Math))\n", - "\n", - "(define expr1 (Mul (Num 2) (Add (Var \"x\") (Num 3))))\n", - "(define expr2 (Add (Num 6) (Mul (Num 2) (Var \"x\"))))\n" - ] - }, - { - "cell_type": "markdown", - "id": "1c0f4ee3-f5bd-49e7-b2a6-81088809eb08", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- User defined sorts\n", - "- Expressions\n", - " - expr1 and expr2 in their own e-classes, we haven't ran any rules\n", - "- `%%egglog` magic, Writing egglog in Notebook, graphs, output inline.\n" + "text/plain": [ + "" ] - }, + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%egglog graph\n", + "(datatype Math\n", + " (Num i64)\n", + " (Var String)\n", + " (Add Math Math)\n", + " (Mul Math Math))\n", + "\n", + "(define expr1 (Mul (Num 2) (Add (Var \"x\") (Num 3))))\n", + "(define expr2 (Add (Num 6) (Mul (Num 2) (Var \"x\"))))\n" + ] + }, + { + "cell_type": "markdown", + "id": "1c0f4ee3-f5bd-49e7-b2a6-81088809eb08", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- User defined sorts\n", + "- Expressions\n", + " - expr1 and expr2 in their own e-classes, we haven't ran any rules\n", + "- `%%egglog` magic, Writing egglog in Notebook, graphs, output inline.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "4c774ee4-722c-4a3a-b61b-37733b435948", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 10, - "id": "4c774ee4-722c-4a3a-b61b-37733b435948", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.var_7848520443469635519_0\n", - "\n", - "\n", - "cluster_Num.var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500:s->Num.__init___16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519:s->Num.var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__add___7659469028595837896\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519_0\n", - "\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519\n", - "\n", - "\n", - "Num.var\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.var_7848520443469635519_0\n", - "\n", - "\n", - "cluster_Num.var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500:s->Num.__init___16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519:s->Num.var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__add___7659469028595837896\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519_0\n", - "\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519\n", - "\n", - "\n", - "Num.var\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'var': FunctionDecl(arg_types=(TypeRefWithVars(name='String', args=()),), arg_names=('name',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('value',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.var': {ClassMethodRef(class_name='Num', method_name='var')}, 'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, 'Num.__mul__': {MethodRef(class_name='Num', method_name='__mul__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='var'): 'Num.var', ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__mul__'): 'Num.__mul__', MethodRef(class_name='Num', method_name='__ne__'): '!='}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.var_7848520443469635519_0\n", + "\n", + "\n", + "cluster_Num.var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500:s->Num.__init___16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519:s->Num.var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__add___7659469028595837896\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519_0\n", + "\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519\n", + "\n", + "\n", + "Num.var\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph = EGraph()\n", - "\n", - "\n", - "@egraph.class_\n", - "class Num(Expr):\n", - " @classmethod\n", - " def var(cls, name: StringLike) -> Num:\n", - " ...\n", - "\n", - " def __init__(self, value: i64Like) -> None:\n", - " ...\n", - "\n", - " def __add__(self, other: Num) -> Num:\n", - " ...\n", - "\n", - " def __mul__(self, other: Num) -> Num:\n", - " ...\n", - "\n", - "\n", - "expr1 = egraph.let(\"expr1\", Num(2) * (Num.var(\"x\") + Num(3)))\n", - "expr2 = egraph.let(\"expr2\", Num(6) + Num(2) * Num.var(\"x\"))\n", - "egraph" - ] - }, - { - "cell_type": "markdown", - "id": "1e32a7c4-fbb7-4dd2-8af1-c7fd22a3ca86", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Re-use existing Python class and functions\n", - " - Humans and computers to understand the typing semantics\n", - " - Humans read `__init__` and `__add__`.\n", - " - Static type checkers. `Num(\"String\")` it won't work.\n", - " - Static type checking drives much of the API design of the library\n", - "- Operator overloading support infix operators\n", - "- Names generated based on classes\n", - " - Same operator on different types compile to different function with different signature\n" - ] - }, - { - "cell_type": "markdown", - "id": "6efa3a03-cce0-4075-a767-84da0a7aec86", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Rewrite rules and checks\n" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "99cb645c-f006-4e9e-bc39-762be3fa5d61", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Var_7848520443469635519_0\n", - "\n", - "\n", - "cluster_Var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_10\n", - "\n", - "\n", - "cluster_10\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359:s->Num_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906:s->Num_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_7848520443469635519:s->Var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896:s->Num_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896:s->Var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7784354942592584825:s->Num_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7784354942592584825:s->Var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_9842753449732275747:s->Mul_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_9842753449732275747:s->Num_16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_11849178328430774015:s->Mul_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_11849178328430774015:s->Mul_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359:s->Add_7784354942592584825\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453:s->Var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_11743562013128004906:s->Num_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_11743562013128004906:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102:s->Num_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_7848520443469635519_0\n", - "\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102_0\n", - "\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359\n", - "\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906\n", - "\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_7848520443469635519\n", - "\n", - "\n", - "Var\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896\n", - "\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7784354942592584825\n", - "\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_9842753449732275747\n", - "\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_11849178328430774015\n", - "\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359\n", - "\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453\n", - "\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_11743562013128004906\n", - "\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102\n", - "\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.var_7848520443469635519_0\n", + "\n", + "\n", + "cluster_Num.var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500:s->Num.__init___16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519:s->Num.var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__add___7659469028595837896\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519_0\n", + "\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519\n", + "\n", + "\n", + "Num.var\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "%%egglog graph continue\n", - "(rewrite (Add a b)\n", - " (Add b a))\n", - "(rewrite (Mul a (Add b c))\n", - " (Add (Mul a b) (Mul a c)))\n", - "(rewrite (Add (Num a) (Num b))\n", - " (Num (+ a b)))\n", - "(rewrite (Mul (Num a) (Num b))\n", - " (Num (* a b)))\n", - "\n", - "(run 10)\n", - "(check (= expr1 expr2))\n" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'var': FunctionDecl(arg_types=(TypeRefWithVars(name='String', args=()),), arg_names=('name',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('value',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.var': {ClassMethodRef(class_name='Num', method_name='var')}, 'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, 'Num.__mul__': {MethodRef(class_name='Num', method_name='__mul__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='var'): 'Num.var', ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__mul__'): 'Num.__mul__', MethodRef(class_name='Num', method_name='__ne__'): '!='}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] - }, - { - "cell_type": "markdown", - "id": "0f5ef7d7-e043-40ee-a334-2e9b34a7b33f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- See equivalent, in same e-class now\n" - ] - }, + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph()\n", + "\n", + "\n", + "@egraph.class_\n", + "class Num(Expr):\n", + " @classmethod\n", + " def var(cls, name: StringLike) -> Num: ...\n", + "\n", + " def __init__(self, value: i64Like) -> None: ...\n", + "\n", + " def __add__(self, other: Num) -> Num: ...\n", + "\n", + " def __mul__(self, other: Num) -> Num: ...\n", + "\n", + "\n", + "expr1 = egraph.let(\"expr1\", Num(2) * (Num.var(\"x\") + Num(3)))\n", + "expr2 = egraph.let(\"expr2\", Num(6) + Num(2) * Num.var(\"x\"))\n", + "egraph" + ] + }, + { + "cell_type": "markdown", + "id": "1e32a7c4-fbb7-4dd2-8af1-c7fd22a3ca86", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Re-use existing Python class and functions\n", + " - Humans and computers to understand the typing semantics\n", + " - Humans read `__init__` and `__add__`.\n", + " - Static type checkers. `Num(\"String\")` it won't work.\n", + " - Static type checking drives much of the API design of the library\n", + "- Operator overloading support infix operators\n", + "- Names generated based on classes\n", + " - Same operator on different types compile to different function with different signature\n" + ] + }, + { + "cell_type": "markdown", + "id": "6efa3a03-cce0-4075-a767-84da0a7aec86", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### Rewrite rules and checks\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "99cb645c-f006-4e9e-bc39-762be3fa5d61", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 12, - "id": "a7f568af-5655-4926-bb93-5c2415f267cb", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.var_7848520443469635519_0\n", - "\n", - "\n", - "cluster_Num.var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_10\n", - "\n", - "\n", - "cluster_10\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519:s->Num.var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__add___7784354942592584825\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747:s->Num.__init___16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015:s->Num.__mul___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519_0\n", - "\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519\n", - "\n", - "\n", - "Num.var\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.var_7848520443469635519_0\n", - "\n", - "\n", - "cluster_Num.var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_10\n", - "\n", - "\n", - "cluster_10\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519:s->Num.var_7848520443469635519_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__add___7784354942592584825\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747:s->Num.__init___16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015:s->Num.__mul___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825:s->Num.var_7848520443469635519\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519_0\n", - "\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_7848520443469635519\n", - "\n", - "\n", - "Num.var\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906\n", - "\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'var': FunctionDecl(arg_types=(TypeRefWithVars(name='String', args=()),), arg_names=('name',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('value',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.var': {ClassMethodRef(class_name='Num', method_name='var')}, 'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, 'Num.__mul__': {MethodRef(class_name='Num', method_name='__mul__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='var'): 'Num.var', ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__mul__'): 'Num.__mul__', MethodRef(class_name='Num', method_name='__ne__'): '!='}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Var_7848520443469635519_0\n", + "\n", + "\n", + "cluster_Var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_10\n", + "\n", + "\n", + "cluster_10\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359:s->Num_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906:s->Num_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_7848520443469635519:s->Var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896:s->Num_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896:s->Var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7784354942592584825:s->Num_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7784354942592584825:s->Var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_9842753449732275747:s->Mul_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_9842753449732275747:s->Num_16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_11849178328430774015:s->Mul_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_11849178328430774015:s->Mul_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359:s->Add_7784354942592584825\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453:s->Var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_11743562013128004906:s->Num_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_11743562013128004906:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102:s->Num_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_7848520443469635519_0\n", + "\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102_0\n", + "\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359\n", + "\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906\n", + "\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_7848520443469635519\n", + "\n", + "\n", + "Var\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896\n", + "\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7784354942592584825\n", + "\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_9842753449732275747\n", + "\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_11849178328430774015\n", + "\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359\n", + "\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453\n", + "\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_11743562013128004906\n", + "\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102\n", + "\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "@egraph.register\n", - "def _(a: Num, b: Num, c: Num, i: i64, j: i64):\n", - " yield rewrite(a + b).to(b + a)\n", - " yield rewrite(a * (b + c)).to((a * b) + (a * c))\n", - " yield rewrite(Num(i) + Num(j)).to(Num(i + j))\n", - " yield rewrite(Num(i) * Num(j)).to(Num(i * j))\n", - "\n", - "\n", - "egraph.run(10)\n", - "egraph.check(eq(expr1).to(expr2))\n", - "egraph" - ] - }, - { - "cell_type": "markdown", - "id": "208b3db5-e2d7-48f8-afaf-e637c132691e", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Similar in Python, rewrite rules, run, check\n", - "- Notice that all vars need types, unlike inferred in egglog\n", - " - Both for static type checkers to verify\n", - " - And for runtime to know what methods\n" + "text/plain": [ + "" ] - }, - { - "cell_type": "markdown", - "id": "cd095e65-074d-44d1-b180-060aa34a92d7", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Extracting lowest cost expression\n" - ] - }, + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%egglog graph continue\n", + "(rewrite (Add a b)\n", + " (Add b a))\n", + "(rewrite (Mul a (Add b c))\n", + " (Add (Mul a b) (Mul a c)))\n", + "(rewrite (Add (Num a) (Num b))\n", + " (Num (+ a b)))\n", + "(rewrite (Mul (Num a) (Num b))\n", + " (Num (* a b)))\n", + "\n", + "(run 10)\n", + "(check (= expr1 expr2))\n" + ] + }, + { + "cell_type": "markdown", + "id": "0f5ef7d7-e043-40ee-a334-2e9b34a7b33f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- See equivalent, in same e-class now\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "a7f568af-5655-4926-bb93-5c2415f267cb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 13, - "id": "33644682-1e44-4d30-9ed8-9126ff00582b", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Extracted with cost 8: (Mul (Num 2) (Add (Var \"x\") (Num 3)))\n" - ] - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.var_7848520443469635519_0\n", + "\n", + "\n", + "cluster_Num.var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_10\n", + "\n", + "\n", + "cluster_10\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519:s->Num.var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__add___7784354942592584825\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747:s->Num.__init___16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015:s->Num.__mul___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519_0\n", + "\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519\n", + "\n", + "\n", + "Num.var\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "%%egglog continue output\n", - "(extract expr1)\n" - ] - }, - { - "cell_type": "markdown", - "id": "b8932052-014c-4e93-b3f3-b8e112b77811", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Extract lowest cost expr\n" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "63308ba8-f31a-4809-bf4a-c6816cbcdc00", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(Num(2) * Num.var(\"x\")) + Num(6)" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.var_7848520443469635519_0\n", + "\n", + "\n", + "cluster_Num.var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_10\n", + "\n", + "\n", + "cluster_10\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519:s->Num.var_7848520443469635519_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__add___7784354942592584825\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747:s->Num.__init___16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015:s->Num.__mul___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825:s->Num.var_7848520443469635519\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519_0\n", + "\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_7848520443469635519\n", + "\n", + "\n", + "Num.var\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906\n", + "\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph.extract(expr1)" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'var': FunctionDecl(arg_types=(TypeRefWithVars(name='String', args=()),), arg_names=('name',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('value',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.var': {ClassMethodRef(class_name='Num', method_name='var')}, 'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, 'Num.__mul__': {MethodRef(class_name='Num', method_name='__mul__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='var'): 'Num.var', ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__mul__'): 'Num.__mul__', MethodRef(class_name='Num', method_name='__ne__'): '!='}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] - }, + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@egraph.register\n", + "def _(a: Num, b: Num, c: Num, i: i64, j: i64):\n", + " yield rewrite(a + b).to(b + a)\n", + " yield rewrite(a * (b + c)).to((a * b) + (a * c))\n", + " yield rewrite(Num(i) + Num(j)).to(Num(i + j))\n", + " yield rewrite(Num(i) * Num(j)).to(Num(i * j))\n", + "\n", + "\n", + "egraph.run(10)\n", + "egraph.check(eq(expr1).to(expr2))\n", + "egraph" + ] + }, + { + "cell_type": "markdown", + "id": "208b3db5-e2d7-48f8-afaf-e637c132691e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Similar in Python, rewrite rules, run, check\n", + "- Notice that all vars need types, unlike inferred in egglog\n", + " - Both for static type checkers to verify\n", + " - And for runtime to know what methods\n" + ] + }, + { + "cell_type": "markdown", + "id": "cd095e65-074d-44d1-b180-060aa34a92d7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### Extracting lowest cost expression\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "33644682-1e44-4d30-9ed8-9126ff00582b", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "386bb340-06a1-4c86-88ba-33201d4214ca", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- get back expr object\n", - "- Str representation is Python syntax\n" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Extracted with cost 8: (Mul (Num 2) (Add (Var \"x\") (Num 3)))\n" + ] + } + ], + "source": [ + "%%egglog continue output\n", + "(extract expr1)\n" + ] + }, + { + "cell_type": "markdown", + "id": "b8932052-014c-4e93-b3f3-b8e112b77811", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Extract lowest cost expr\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "63308ba8-f31a-4809-bf4a-c6816cbcdc00", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "f5e0d729-028a-4af4-947f-62a2e109d28a", - "metadata": { - "editable": true, - "jp-MarkdownHeadingCollapsed": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Multipart Rules\n" + "data": { + "text/plain": [ + "(Num(2) * Num.var(\"x\")) + Num(6)" ] - }, + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.extract(expr1)" + ] + }, + { + "cell_type": "markdown", + "id": "386bb340-06a1-4c86-88ba-33201d4214ca", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- get back expr object\n", + "- Str representation is Python syntax\n" + ] + }, + { + "cell_type": "markdown", + "id": "f5e0d729-028a-4af4-947f-62a2e109d28a", + "metadata": { + "editable": true, + "jp-MarkdownHeadingCollapsed": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### Multipart Rules\n" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "0bea7d72-bf5c-47c4-95ac-e2926ad33cf3", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 15, - "id": "0bea7d72-bf5c-47c4-95ac-e2926ad33cf3", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_16783941965674463102\n", - "\n", - "\n", - "cluster_fib_16783941965674463102\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_16783941965674463102_0\n", - "\n", - "\n", - "cluster_fib_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906\n", - "\n", - "\n", - "cluster_fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196\n", - "\n", - "\n", - "cluster_fib_5040379952546458196\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_10080759905092916392_0\n", - "\n", - "\n", - "cluster_fib_10080759905092916392_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359\n", - "\n", - "\n", - "cluster_fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0\n", - "\n", - "\n", - "cluster_fib_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_10912160959110460649_0\n", - "\n", - "\n", - "cluster_fib_10912160959110460649_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_4208978898528913939\n", - "\n", - "\n", - "cluster_fib_4208978898528913939\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_10080759905092916392\n", - "\n", - "\n", - "cluster_fib_10080759905092916392\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453\n", - "\n", - "\n", - "cluster_fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_4208978898528913939_0\n", - "\n", - "\n", - "cluster_fib_4208978898528913939_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_10912160959110460649\n", - "\n", - "\n", - "cluster_fib_10912160959110460649\n", - "\n", - "\n", - "\n", - "\n", - "fib_16783941965674463102:s->fib_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_4208978898528913939:s->fib_4208978898528913939_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10080759905092916392:s->fib_10080759905092916392_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10912160959110460649:s->fib_10912160959110460649_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_16783941965674463102\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_16783941965674463102_value\n", - "\n", - "\n", - "8\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_16783941965674463102_0\n", - "\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_value\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_value\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10080759905092916392_0\n", - "\n", - "\n", - "8\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_value\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_value\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10912160959110460649_0\n", - "\n", - "\n", - "5\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_4208978898528913939\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_4208978898528913939_value\n", - "\n", - "\n", - "13\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10080759905092916392\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10080759905092916392_value\n", - "\n", - "\n", - "21\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_value\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_4208978898528913939_0\n", - "\n", - "\n", - "7\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10912160959110460649\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10912160959110460649_value\n", - "\n", - "\n", - "5\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_16783941965674463102\n", + "\n", + "\n", + "cluster_fib_16783941965674463102\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_16783941965674463102_0\n", + "\n", + "\n", + "cluster_fib_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906\n", + "\n", + "\n", + "cluster_fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196\n", + "\n", + "\n", + "cluster_fib_5040379952546458196\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_10080759905092916392_0\n", + "\n", + "\n", + "cluster_fib_10080759905092916392_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359\n", + "\n", + "\n", + "cluster_fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0\n", + "\n", + "\n", + "cluster_fib_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_10912160959110460649_0\n", + "\n", + "\n", + "cluster_fib_10912160959110460649_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_4208978898528913939\n", + "\n", + "\n", + "cluster_fib_4208978898528913939\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_10080759905092916392\n", + "\n", + "\n", + "cluster_fib_10080759905092916392\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453\n", + "\n", + "\n", + "cluster_fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_4208978898528913939_0\n", + "\n", + "\n", + "cluster_fib_4208978898528913939_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_10912160959110460649\n", + "\n", + "\n", + "cluster_fib_10912160959110460649\n", + "\n", + "\n", + "\n", + "\n", + "fib_16783941965674463102:s->fib_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_4208978898528913939:s->fib_4208978898528913939_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10080759905092916392:s->fib_10080759905092916392_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10912160959110460649:s->fib_10912160959110460649_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_16783941965674463102\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_16783941965674463102_value\n", + "\n", + "\n", + "8\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_16783941965674463102_0\n", + "\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_value\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_value\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10080759905092916392_0\n", + "\n", + "\n", + "8\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_value\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_value\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10912160959110460649_0\n", + "\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_4208978898528913939\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_4208978898528913939_value\n", + "\n", + "\n", + "13\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10080759905092916392\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10080759905092916392_value\n", + "\n", + "\n", + "21\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_value\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_4208978898528913939_0\n", + "\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10912160959110460649\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10912160959110460649_value\n", + "\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "%%egglog graph\n", - "(function fib (i64) i64)\n", - "\n", - "(set (fib 0) 0)\n", - "(set (fib 1) 1)\n", - "(rule ((= f0 (fib x))\n", - " (= f1 (fib (+ x 1))))\n", - " ((set (fib (+ x 2)) (+ f0 f1))))\n", - "\n", - "(run 7)\n", - "(check (= (fib 7) 13))\n" + "text/plain": [ + "" ] - }, - { - "cell_type": "markdown", - "id": "2dc964ef-f5ee-4b7c-80a5-5a11b848ece7", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Rule that depend on facts and execute actions\n" - ] - }, + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%egglog graph\n", + "(function fib (i64) i64)\n", + "\n", + "(set (fib 0) 0)\n", + "(set (fib 1) 1)\n", + "(rule ((= f0 (fib x))\n", + " (= f1 (fib (+ x 1))))\n", + " ((set (fib (+ x 2)) (+ f0 f1))))\n", + "\n", + "(run 7)\n", + "(check (= (fib 7) 13))\n" + ] + }, + { + "cell_type": "markdown", + "id": "2dc964ef-f5ee-4b7c-80a5-5a11b848ece7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Rule that depend on facts and execute actions\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "7f4bd927-ccd6-4240-aec0-123d93a782c5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "fib_egraph = EGraph()\n", + "\n", + "\n", + "@fib_egraph.function\n", + "def fib(x: i64Like) -> i64: ...\n", + "\n", + "\n", + "@fib_egraph.register\n", + "def _(f0: i64, f1: i64, x: i64):\n", + " yield set_(fib(0)).to(i64(1))\n", + " yield set_(fib(1)).to(i64(1))\n", + " yield rule(\n", + " eq(f0).to(fib(x)),\n", + " eq(f1).to(fib(x + 1)),\n", + " ).then(set_(fib(x + 2)).to(f0 + f1))\n", + "\n", + "\n", + "fib_egraph.run(7)\n", + "fib_egraph.check(eq(fib(7)).to(i64(21)))" + ] + }, + { + "cell_type": "markdown", + "id": "df10f994-3e91-4663-807a-877f3dd50e04", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- `set_` and and `eq` both type safe. Required builder syntax\n" + ] + }, + { + "cell_type": "markdown", + "id": "5b4d8cba-3e99-4e61-afe0-c18724c0d358", + "metadata": { + "editable": true, + "jp-MarkdownHeadingCollapsed": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### Include & Modules\n" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "68179969-f9e0-43ef-851f-bd2295bd5a21", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 16, - "id": "7f4bd927-ccd6-4240-aec0-123d93a782c5", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "fib_egraph = EGraph()\n", - "\n", - "\n", - "@fib_egraph.function\n", - "def fib(x: i64Like) -> i64:\n", - " ...\n", - "\n", - "\n", - "@fib_egraph.register\n", - "def _(f0: i64, f1: i64, x: i64):\n", - " yield set_(fib(0)).to(i64(1))\n", - " yield set_(fib(1)).to(i64(1))\n", - " yield rule(\n", - " eq(f0).to(fib(x)),\n", - " eq(f1).to(fib(x + 1)),\n", - " ).then(set_(fib(x + 2)).to(f0 + f1))\n", - "\n", - "\n", - "fib_egraph.run(7)\n", - "fib_egraph.check(eq(fib(7)).to(i64(21)))" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting path.egg\n" + ] + } + ], + "source": [ + "%%writefile path.egg\n", + "(relation path (i64 i64))\n", + "(relation edge (i64 i64))\n", + "\n", + "(rule ((edge x y))\n", + " ((path x y)))\n", + "\n", + "(rule ((path x y) (edge y z))\n", + " ((path x z)))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "39273d7a-926c-4022-8514-8f5b297cfdfb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "%%egglog\n", + "(include \"path.egg\")\n", + "(edge 1 2)\n", + "(edge 2 3)\n", + "(edge 3 4)\n", + "(run 3)\n", + "(check (path 1 3))\n" + ] + }, + { + "cell_type": "markdown", + "id": "ac6aec27-654d-4cf5-bb4e-3341074ffa64", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Include another file for re-useability\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "ad42a38e-ad5d-476b-8ecb-a04a56a618d1", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "mod = Module()\n", + "path = mod.relation(\"path\", i64, i64)\n", + "edge = mod.relation(\"edge\", i64, i64)\n", + "\n", + "\n", + "@mod.register\n", + "def _(x: i64, y: i64, z: i64):\n", + " yield rule(edge(x, y)).then(path(x, y))\n", + " yield rule(path(x, y), edge(y, z)).then(path(x, z))" + ] + }, + { + "cell_type": "markdown", + "id": "93b04224-cf27-41aa-b3e8-4fb5f5bb1508", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Modules same in Python\n", + "- Supports defining rules, etc, but doesn't actually run them, just builds up commands\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "8f8932a2-f6ea-4a7c-a4f3-41e4455aa33e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "egraph = EGraph([mod])\n", + "egraph.register(edge(1, 2), edge(2, 3), edge(3, 4))\n", + "egraph.run(3)\n", + "egraph.check(path(1, 3))" + ] + }, + { + "cell_type": "markdown", + "id": "99f0f9f2-297d-45ac-bc84-053f591d894d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Then when we depend on them, it will run those commands first.\n", + "- Allows distribution of code and others to re-use it, using existing Python import mechanisms.\n" + ] + }, + { + "cell_type": "markdown", + "id": "08d88a72-6271-41eb-91f4-978d86b4f5ff", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### Python Objects\n", + "\n", + "`egglog` supports `i64`, `f64`, `String`, `Vec`, `Map`, `Set`...\n", + "\n", + "But what if I want to store a Python object in my e-graph?\n" + ] + }, + { + "cell_type": "code", + "execution_count": 61, + "id": "be92f5ff-caf3-492e-a338-2db7e559cc2b", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "df10f994-3e91-4663-807a-877f3dd50e04", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- `set_` and and `eq` both type safe. Required builder syntax\n" + "data": { + "text/plain": [ + "PyObject(277923772, 1)" ] - }, + }, + "execution_count": 61, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph()\n", + "res = egraph.save_object(True)\n", + "# Saves reference to object and stores in e-graph as type and value hashes:\n", + "res" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "e207b2d9-533d-4e04-9c22-2856fe306385", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "5b4d8cba-3e99-4e61-afe0-c18724c0d358", - "metadata": { - "editable": true, - "jp-MarkdownHeadingCollapsed": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Include & Modules\n" + "data": { + "text/plain": [ + "True" ] - }, + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.load_object(res)" + ] + }, + { + "cell_type": "markdown", + "id": "9c7986e4-0868-4489-8b66-3a30100c548d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "source": [ + "Can eval arbitrary python code:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 62, + "id": "d2c28413-a7f1-41ed-9675-5cf13bba9eba", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 17, - "id": "68179969-f9e0-43ef-851f-bd2295bd5a21", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Overwriting path.egg\n" - ] - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "%%writefile path.egg\n", - "(relation path (i64 i64))\n", - "(relation edge (i64 i64))\n", - "\n", - "(rule ((edge x y))\n", - " ((path x y)))\n", - "\n", - "(rule ((path x y) (edge y z))\n", - " ((path x z)))\n" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "39273d7a-926c-4022-8514-8f5b297cfdfb", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "%%egglog\n", - "(include \"path.egg\")\n", - "(edge 1 2)\n", - "(edge 2 3)\n", - "(edge 3 4)\n", - "(run 3)\n", - "(check (path 1 3))\n" - ] - }, - { - "cell_type": "markdown", - "id": "ac6aec27-654d-4cf5-bb4e-3341074ffa64", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Include another file for re-useability\n" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "ad42a38e-ad5d-476b-8ecb-a04a56a618d1", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "mod = Module()\n", - "path = mod.relation(\"path\", i64, i64)\n", - "edge = mod.relation(\"edge\", i64, i64)\n", - "\n", - "\n", - "@mod.register\n", - "def _(x: i64, y: i64, z: i64):\n", - " yield rule(edge(x, y)).then(path(x, y))\n", - " yield rule(path(x, y), edge(y, z)).then(path(x, z))" - ] - }, - { - "cell_type": "markdown", - "id": "93b04224-cf27-41aa-b3e8-4fb5f5bb1508", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Modules same in Python\n", - "- Supports defining rules, etc, but doesn't actually run them, just builds up commands\n" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "id": "8f8932a2-f6ea-4a7c-a4f3-41e4455aa33e", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "egraph = EGraph([mod])\n", - "egraph.register(edge(1, 2), edge(2, 3), edge(3, 4))\n", - "egraph.run(3)\n", - "egraph.check(path(1, 3))" - ] - }, - { - "cell_type": "markdown", - "id": "99f0f9f2-297d-45ac-bc84-053f591d894d", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Then when we depend on them, it will run those commands first.\n", - "- Allows distribution of code and others to re-use it, using existing Python import mechanisms.\n" - ] - }, - { - "cell_type": "markdown", - "id": "08d88a72-6271-41eb-91f4-978d86b4f5ff", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Python Objects\n", - "\n", - "`egglog` supports `i64`, `f64`, `String`, `Vec`, `Map`, `Set`...\n", - "\n", - "But what if I want to store a Python object in my e-graph?\n" - ] - }, - { - "cell_type": "code", - "execution_count": 61, - "id": "be92f5ff-caf3-492e-a338-2db7e559cc2b", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "PyObject(277923772, 1)" - ] - }, - "execution_count": 61, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph = EGraph()\n", - "res = egraph.save_object(True)\n", - "# Saves reference to object and stores in e-graph as type and value hashes:\n", - "res" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'py-object': set()}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" ] - }, + }, + "execution_count": 62, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "empty_dict = egraph.save_object({})\n", + "locals_ = empty_dict.dict_update(egraph.save_object(\"x\"), res)\n", + "\n", + "egraph.load_object(egraph.extract(py_eval(\"not x\", locals_, empty_dict)))" + ] + }, + { + "cell_type": "markdown", + "id": "ee9e839d-d6c1-4161-af7b-b9db5cd42716", + "metadata": { + "editable": true, + "jp-MarkdownHeadingCollapsed": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### \"Preserved\" methods\n", + "\n", + "...from egglog to Python...\n" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "26cf3d77-0013-4025-8db0-846eba404798", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "egraph = EGraph()\n", + "\n", + "\n", + "@egraph.class_\n", + "class Bool(Expr):\n", + " def to_py(self) -> PyObject: ...\n", + "\n", + " def __or__(self, other: Bool) -> Bool: ...\n", + "\n", + " # This will get executed eagerly\n", + " @egraph.method(preserve=True)\n", + " def __bool__(self) -> bool:\n", + " print(self)\n", + " egraph.register(self)\n", + " egraph.run(run(limit=10).saturate())\n", + " print(f\" -> {egraph.extract(self)}\")\n", + " return egraph.load_object(egraph.extract(self.to_py()))\n", + "\n", + "\n", + "TRUE = egraph.constant(\"TRUE\", Bool)\n", + "FALSE = egraph.constant(\"FALSE\", Bool)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "2034f106-2b50-4410-83d7-dd1feb8365ac", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 22, - "id": "e207b2d9-533d-4e04-9c22-2856fe306385", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "egraph.load_object(res)" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "TRUE | FALSE\n", + " -> TRUE | FALSE\n" + ] }, { - "cell_type": "markdown", - "id": "9c7986e4-0868-4489-8b66-3a30100c548d", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "Can eval arbitrary python code:\n" - ] - }, + "ename": "EggSmolError", + "evalue": "Not found: fake expression Bool.to_py [Value { tag: \"Bool\", bits: 2 }]", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mEggSmolError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[25], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mbool\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mTRUE\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m|\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mFALSE\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/runtime.py:403\u001b[0m, in \u001b[0;36m_preserved_method\u001b[0;34m(self, __name)\u001b[0m\n\u001b[1;32m 401\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m:\n\u001b[1;32m 402\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__egg_typed_expr__\u001b[38;5;241m.\u001b[39mtp\u001b[38;5;241m.\u001b[39mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m has no method \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m__name\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 403\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mmethod\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m)\u001b[49m\n", + "Cell \u001b[0;32mIn[24], line 15\u001b[0m, in \u001b[0;36mBool.__bool__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 13\u001b[0m egraph\u001b[38;5;241m.\u001b[39mrun(run(limit\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m10\u001b[39m)\u001b[38;5;241m.\u001b[39msaturate())\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m -> \u001b[39m\u001b[38;5;132;01m{\u001b[39;00megraph\u001b[38;5;241m.\u001b[39mextract(\u001b[38;5;28mself\u001b[39m)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m---> 15\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m egraph\u001b[38;5;241m.\u001b[39mload_object(\u001b[43megraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mextract\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto_py\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m)\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:739\u001b[0m, in \u001b[0;36mEGraph.extract\u001b[0;34m(self, expr)\u001b[0m\n\u001b[1;32m 737\u001b[0m typed_expr \u001b[38;5;241m=\u001b[39m expr_parts(expr)\n\u001b[1;32m 738\u001b[0m egg_expr \u001b[38;5;241m=\u001b[39m typed_expr\u001b[38;5;241m.\u001b[39mto_egg(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_mod_decls)\n\u001b[0;32m--> 739\u001b[0m extract_report \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_extract\u001b[49m\u001b[43m(\u001b[49m\u001b[43megg_expr\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 740\u001b[0m new_typed_expr \u001b[38;5;241m=\u001b[39m TypedExprDecl\u001b[38;5;241m.\u001b[39mfrom_egg(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_mod_decls, extract_report\u001b[38;5;241m.\u001b[39mexpr)\n\u001b[1;32m 741\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m new_typed_expr\u001b[38;5;241m.\u001b[39mtp \u001b[38;5;241m!=\u001b[39m typed_expr\u001b[38;5;241m.\u001b[39mtp:\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:756\u001b[0m, in \u001b[0;36mEGraph._run_extract\u001b[0;34m(self, expr, n)\u001b[0m\n\u001b[1;32m 755\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_run_extract\u001b[39m(\u001b[38;5;28mself\u001b[39m, expr: bindings\u001b[38;5;241m.\u001b[39m_Expr, n: \u001b[38;5;28mint\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39mExtractReport:\n\u001b[0;32m--> 756\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_process_commands\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[43mbindings\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mExtract\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mexpr\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 757\u001b[0m extract_report \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_egraph\u001b[38;5;241m.\u001b[39mextract_report()\n\u001b[1;32m 758\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m extract_report:\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:634\u001b[0m, in \u001b[0;36mEGraph._process_commands\u001b[0;34m(self, commands)\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_process_commands\u001b[39m(\u001b[38;5;28mself\u001b[39m, commands: Iterable[bindings\u001b[38;5;241m.\u001b[39m_Command]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 634\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_egraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_program\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcommands\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[0;31mEggSmolError\u001b[0m: Not found: fake expression Bool.to_py [Value { tag: \"Bool\", bits: 2 }]" + ] + } + ], + "source": [ + "bool(TRUE | FALSE)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "edc2fbb4-051e-4693-90c6-5f169c3f185a", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 62, - "id": "d2c28413-a7f1-41ed-9675-5cf13bba9eba", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'py-object': set()}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" - ] - }, - "execution_count": 62, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "empty_dict = egraph.save_object({})\n", - "locals_ = empty_dict.dict_update(egraph.save_object(\"x\"), res)\n", - "\n", - "egraph.load_object(egraph.extract(py_eval(\"not x\", locals_, empty_dict)))" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "TRUE | FALSE\n", + " -> TRUE\n" + ] }, { - "cell_type": "markdown", - "id": "ee9e839d-d6c1-4161-af7b-b9db5cd42716", - "metadata": { - "editable": true, - "jp-MarkdownHeadingCollapsed": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### \"Preserved\" methods\n", - "\n", - "...from egglog to Python...\n" + "data": { + "text/plain": [ + "True" ] - }, + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@egraph.register\n", + "def _bool(x: Bool):\n", + " return [\n", + " set_(TRUE.to_py()).to(egraph.save_object(True)),\n", + " set_(FALSE.to_py()).to(egraph.save_object(False)),\n", + " rewrite(TRUE | x).to(TRUE),\n", + " rewrite(FALSE | x).to(x),\n", + " ]\n", + "\n", + "\n", + "bool(TRUE | FALSE)" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "ad299bd6-7dd2-4b22-8fa0-4135b486a7e2", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 24, - "id": "26cf3d77-0013-4025-8db0-846eba404798", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "egraph = EGraph()\n", - "\n", - "\n", - "@egraph.class_\n", - "class Bool(Expr):\n", - " def to_py(self) -> PyObject:\n", - " ...\n", - "\n", - " def __or__(self, other: Bool) -> Bool:\n", - " ...\n", - "\n", - " # This will get executed eagerly\n", - " @egraph.method(preserve=True)\n", - " def __bool__(self) -> bool:\n", - " print(self)\n", - " egraph.register(self)\n", - " egraph.run(run(limit=10).saturate())\n", - " print(f\" -> {egraph.extract(self)}\")\n", - " return egraph.load_object(egraph.extract(self.to_py()))\n", - "\n", - "\n", - "TRUE = egraph.constant(\"TRUE\", Bool)\n", - "FALSE = egraph.constant(\"FALSE\", Bool)" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "TRUE | x\n", + " -> TRUE\n", + "it's true!\n" + ] + } + ], + "source": [ + "x = egraph.constant(\"x\", Bool)\n", + "if TRUE | x:\n", + " print(\"it's true!\")" + ] + }, + { + "cell_type": "markdown", + "id": "b995fd39-524f-4df3-a0fb-d7f882e5b00f", + "metadata": { + "editable": true, + "jp-MarkdownHeadingCollapsed": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### Conversions\n", + "\n", + "...from Python to egglog...\n" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "a00b60cd-c34d-4ed7-ac24-f16678a00590", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 25, - "id": "2034f106-2b50-4410-83d7-dd1feb8365ac", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "TRUE | FALSE\n", - " -> TRUE | FALSE\n" - ] - }, - { - "ename": "EggSmolError", - "evalue": "Not found: fake expression Bool.to_py [Value { tag: \"Bool\", bits: 2 }]", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mEggSmolError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[25], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[38;5;28;43mbool\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mTRUE\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m|\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mFALSE\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/runtime.py:403\u001b[0m, in \u001b[0;36m_preserved_method\u001b[0;34m(self, __name)\u001b[0m\n\u001b[1;32m 401\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m:\n\u001b[1;32m 402\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m__egg_typed_expr__\u001b[38;5;241m.\u001b[39mtp\u001b[38;5;241m.\u001b[39mname\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m has no method \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m__name\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 403\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mmethod\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m)\u001b[49m\n", - "Cell \u001b[0;32mIn[24], line 15\u001b[0m, in \u001b[0;36mBool.__bool__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 13\u001b[0m egraph\u001b[38;5;241m.\u001b[39mrun(run(limit\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m10\u001b[39m)\u001b[38;5;241m.\u001b[39msaturate())\n\u001b[1;32m 14\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m -> \u001b[39m\u001b[38;5;132;01m{\u001b[39;00megraph\u001b[38;5;241m.\u001b[39mextract(\u001b[38;5;28mself\u001b[39m)\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m---> 15\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m egraph\u001b[38;5;241m.\u001b[39mload_object(\u001b[43megraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mextract\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto_py\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m)\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:739\u001b[0m, in \u001b[0;36mEGraph.extract\u001b[0;34m(self, expr)\u001b[0m\n\u001b[1;32m 737\u001b[0m typed_expr \u001b[38;5;241m=\u001b[39m expr_parts(expr)\n\u001b[1;32m 738\u001b[0m egg_expr \u001b[38;5;241m=\u001b[39m typed_expr\u001b[38;5;241m.\u001b[39mto_egg(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_mod_decls)\n\u001b[0;32m--> 739\u001b[0m extract_report \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_run_extract\u001b[49m\u001b[43m(\u001b[49m\u001b[43megg_expr\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[1;32m 740\u001b[0m new_typed_expr \u001b[38;5;241m=\u001b[39m TypedExprDecl\u001b[38;5;241m.\u001b[39mfrom_egg(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_mod_decls, extract_report\u001b[38;5;241m.\u001b[39mexpr)\n\u001b[1;32m 741\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m new_typed_expr\u001b[38;5;241m.\u001b[39mtp \u001b[38;5;241m!=\u001b[39m typed_expr\u001b[38;5;241m.\u001b[39mtp:\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:756\u001b[0m, in \u001b[0;36mEGraph._run_extract\u001b[0;34m(self, expr, n)\u001b[0m\n\u001b[1;32m 755\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_run_extract\u001b[39m(\u001b[38;5;28mself\u001b[39m, expr: bindings\u001b[38;5;241m.\u001b[39m_Expr, n: \u001b[38;5;28mint\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39mExtractReport:\n\u001b[0;32m--> 756\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_process_commands\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[43mbindings\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mExtract\u001b[49m\u001b[43m(\u001b[49m\u001b[43mn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mexpr\u001b[49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 757\u001b[0m extract_report \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_egraph\u001b[38;5;241m.\u001b[39mextract_report()\n\u001b[1;32m 758\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m extract_report:\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:634\u001b[0m, in \u001b[0;36mEGraph._process_commands\u001b[0;34m(self, commands)\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_process_commands\u001b[39m(\u001b[38;5;28mself\u001b[39m, commands: Iterable[bindings\u001b[38;5;241m.\u001b[39m_Command]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 634\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_egraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_program\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcommands\u001b[49m\u001b[43m)\u001b[49m\n", - "\u001b[0;31mEggSmolError\u001b[0m: Not found: fake expression Bool.to_py [Value { tag: \"Bool\", bits: 2 }]" - ] - } - ], - "source": [ - "bool(TRUE | FALSE)" + "data": { + "text/plain": [ + "TRUE | FALSE" ] - }, + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "converter(bool, Bool, lambda x: TRUE if x else FALSE)\n", + "\n", + "TRUE | False" + ] + }, + { + "cell_type": "markdown", + "id": "cfc8d51a-5d48-49c5-b4e8-42d3706cab0b", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "- Allow you to do \"upcasting\" which is very common in Python\n", + "- Can get closer to mimicking regular Python APIs\n" + ] + }, + { + "cell_type": "markdown", + "id": "448931df-62ad-4391-8fa8-143ee68258a2", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### Fib Example\n" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "8599335e-19ec-4511-bced-77c7e4d05f68", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 26, - "id": "edc2fbb4-051e-4693-90c6-5f169c3f185a", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "TRUE | FALSE\n", - " -> TRUE\n" - ] - }, - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 26, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "@egraph.register\n", - "def _bool(x: Bool):\n", - " return [\n", - " set_(TRUE.to_py()).to(egraph.save_object(True)),\n", - " set_(FALSE.to_py()).to(egraph.save_object(False)),\n", - " rewrite(TRUE | x).to(TRUE),\n", - " rewrite(FALSE | x).to(x),\n", - " ]\n", - "\n", - "\n", - "bool(TRUE | FALSE)" - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "id": "ad299bd6-7dd2-4b22-8fa0-4135b486a7e2", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "TRUE | x\n", - " -> TRUE\n", - "it's true!\n" - ] - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "x = egraph.constant(\"x\", Bool)\n", - "if TRUE | x:\n", - " print(\"it's true!\")" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] - }, - { - "cell_type": "markdown", - "id": "b995fd39-524f-4df3-a0fb-d7f882e5b00f", - "metadata": { - "editable": true, - "jp-MarkdownHeadingCollapsed": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Conversions\n", - "\n", - "...from Python to egglog...\n" - ] - }, + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph()\n", + "\n", + "\n", + "@egraph.class_\n", + "class Num(Expr):\n", + " def __init__(self, i: i64Like) -> None: ...\n", + "\n", + " def __add__(self, other: Num) -> Num: ...\n", + "\n", + "\n", + "@egraph.function\n", + "def fib(x: i64Like) -> Num: ...\n", + "\n", + "\n", + "@egraph.register\n", + "def _fib(a: i64, b: i64, x: i64, f: Num):\n", + " return [\n", + " rewrite(Num(a) + Num(b)).to(Num(a + b)),\n", + " rule(eq(f).to(fib(x)), x > 1).then(set_(fib(x)).to(fib(x - 1) + fib(x - 2))),\n", + " set_(fib(0)).to(Num(0)),\n", + " set_(fib(1)).to(Num(1)),\n", + " ]\n", + "\n", + "\n", + "egraph" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "80aafdc2-90a6-46ef-b2a4-6559b26457f7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 28, - "id": "a00b60cd-c34d-4ed7-ac24-f16678a00590", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "TRUE | FALSE" - ] - }, - "execution_count": 28, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "converter(bool, Bool, lambda x: TRUE if x else FALSE)\n", - "\n", - "TRUE | False" - ] - }, - { - "cell_type": "markdown", - "id": "cfc8d51a-5d48-49c5-b4e8-42d3706cab0b", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "- Allow you to do \"upcasting\" which is very common in Python\n", - "- Can get closer to mimicking regular Python APIs\n" - ] - }, - { - "cell_type": "markdown", - "id": "448931df-62ad-4391-8fa8-143ee68258a2", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Fib Example\n" - ] - }, - { - "cell_type": "code", - "execution_count": 52, - "id": "8599335e-19ec-4511-bced-77c7e4d05f68", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 52, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph = EGraph()\n", - "\n", - "\n", - "@egraph.class_\n", - "class Num(Expr):\n", - " def __init__(self, i: i64Like) -> None:\n", - " ...\n", - "\n", - " def __add__(self, other: Num) -> Num:\n", - " ...\n", - "\n", - "\n", - "@egraph.function\n", - "def fib(x: i64Like) -> Num:\n", - " ...\n", - "\n", - "\n", - "@egraph.register\n", - "def _fib(a: i64, b: i64, x: i64, f: Num):\n", - " return [\n", - " rewrite(Num(a) + Num(b)).to(Num(a + b)),\n", - " rule(eq(f).to(fib(x)), x > 1).then(set_(fib(x)).to(fib(x - 1) + fib(x - 2))),\n", - " set_(fib(0)).to(Num(0)),\n", - " set_(fib(1)).to(Num(1)),\n", - " ]\n", - "\n", - "\n", - "egraph" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] - }, + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "f4 = egraph.let(\"f4\", fib(4))\n", + "egraph" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "ebb3e6eb-bf39-49d8-9edd-0db5c04964d4", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 53, - "id": "80aafdc2-90a6-46ef-b2a4-6559b26457f7", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 53, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "f4 = egraph.let(\"f4\", fib(4))\n", - "egraph" - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "id": "ebb3e6eb-bf39-49d8-9edd-0db5c04964d4", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph.run(1)\n", - "egraph" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] - }, + }, + "execution_count": 54, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.run(1)\n", + "egraph" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "908e3391-156f-4d4c-ac0f-8f059647e511", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 55, - "id": "908e3391-156f-4d4c-ac0f-8f059647e511", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___956286968014291186:s->fib_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___956286968014291186:s->fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___6267377405668604861:s->Num.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___6267377405668604861:s->Num.__add___956286968014291186\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___956286968014291186\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___6267377405668604861\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___956286968014291186:s->fib_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___956286968014291186:s->fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___6267377405668604861:s->Num.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___6267377405668604861:s->Num.__add___956286968014291186\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___956286968014291186\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___6267377405668604861\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___956286968014291186:s->fib_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___956286968014291186:s->fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___6267377405668604861:s->Num.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___6267377405668604861:s->Num.__add___956286968014291186\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___956286968014291186\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___6267377405668604861\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph.run(1)\n", - "egraph" - ] - }, - { - "cell_type": "code", - "execution_count": 56, - "id": "cf868ab3-c0ff-4719-9b95-e937e61ebd2d", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 56, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___956286968014291186:s->fib_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___956286968014291186:s->fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___6267377405668604861:s->Num.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___6267377405668604861:s->Num.__add___956286968014291186\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___956286968014291186\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___6267377405668604861\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph.run(1)\n", - "egraph" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] - }, + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.run(1)\n", + "egraph" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "cf868ab3-c0ff-4719-9b95-e937e61ebd2d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 57, - "id": "9283b1d4-f83d-4796-98b7-de1b4e5b2a67", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 57, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph.run(1)\n", - "egraph" - ] - }, - { - "cell_type": "code", - "execution_count": 59, - "id": "0aef5e81-43e3-4001-bf7a-b692fb3ff4b4", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Num(3)\n" - ] - }, - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___0_0\n", - "\n", - "\n", - "cluster_Num.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0:s->Num.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408:s->fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453_0\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___0\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___395596399104602408\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___5871781006564002453\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___16275225025205966978\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "f4_0\n", - "\n", - "\n", - "f4\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___5435976351651060604\n", - "\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 59, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph.run(1)\n", - "print(egraph.extract(f4))\n", - "egraph" - ] - }, - { - "cell_type": "markdown", - "id": "a037bf31-2637-470a-ae26-b56538f689a6", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### A story about Arrays\n" - ] - }, - { - "cell_type": "markdown", - "id": "082d9334-86e2-42a1-92f4-08563902b064", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- This is one path through a huge maze of use cases.\n", - "- Does not represent one killer example, but is an area I am familar with based on my previous work\n" - ] - }, - { - "cell_type": "markdown", - "id": "24955a1a-d3d6-44d8-a7ee-b5a87bd2a153", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "#### 1. Someone makes an NDArray library...\n" - ] - }, - { - "cell_type": "code", - "execution_count": 29, - "id": "be2f1cb2-81c1-485d-8eb9-06c4d8b3c6ba", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "ndarray_mod = Module()\n", - "..." - ] - }, - { - "cell_type": "code", - "execution_count": 30, - "id": "b0d83999-9aac-4881-a81a-385541b621fb", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "@ndarray_mod.class_\n", - "class Value(Expr):\n", - " def __init__(self, v: i64Like) -> None:\n", - " ...\n", - "\n", - " def __mul__(self, other: Value) -> Value:\n", - " ...\n", - "\n", - " def __add__(self, other: Value) -> Value:\n", - " ...\n", - "\n", - "\n", - "i, j = vars_(\"i j\", i64)\n", - "ndarray_mod.register(\n", - " rewrite(Value(i) * Value(j)).to(Value(i * j)),\n", - " rewrite(Value(i) + Value(j)).to(Value(i + j)),\n", - ")\n", - "\n", - "\n", - "@ndarray_mod.class_\n", - "class Values(Expr):\n", - " def __init__(self, v: Vec[Value]) -> None:\n", - " ...\n", - "\n", - " def __getitem__(self, idx: Value) -> Value:\n", - " ...\n", - "\n", - " def length(self) -> Value:\n", - " ...\n", - "\n", - " def concat(self, other: Values) -> Values:\n", - " ...\n", - "\n", - "\n", - "@ndarray_mod.register\n", - "def _values(vs: Vec[Value], other: Vec[Value]):\n", - " yield rewrite(Values(vs)[Value(i)]).to(vs[i])\n", - " yield rewrite(Values(vs).length()).to(Value(vs.length()))\n", - " yield rewrite(Values(vs).concat(Values(other))).to(Values(vs.append(other)))" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "0a9c6dfd-21b6-4e28-abe4-1bc8d8229a5a", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "@ndarray_mod.class_\n", - "class NDArray(Expr):\n", - " def __getitem__(self, idx: Values) -> Value:\n", - " ...\n", - "\n", - " def shape(self) -> Values:\n", - " ...\n", - "\n", - "\n", - "@ndarray_mod.function\n", - "def arange(n: Value) -> NDArray:\n", - " ..." - ] - }, - { - "cell_type": "markdown", - "id": "36dd2603-c60e-42d0-a5d5-98043ed307a5", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Basic\n", - "- One function, range, get shape and index into array\n", - "- Very different from existing paradigms in Python... Inheritance, multi-dispatch, dunder protocols.\n", - " - Entirely open protocol.\n", - " - Anyone else could define ways to create arrays\n", - " - About mathematical definition really. This is from M\n" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] - }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "0f36b591-9a20-4405-80cb-3dbfea11b129", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "Restifo Mullin, Lenore Marie, \"A mathematics of arrays\" (1988). _Electrical Engineering and Computer Science - Dissertations_. 249.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 32, - "id": "3e020ae8-29a3-4e35-8510-aa2639c87701", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "@ndarray_mod.register\n", - "def _(n: Value, idx: Values, a: NDArray):\n", - " yield rewrite(arange(n).shape()).to(Values(Vec(n)))\n", - " yield rewrite(arange(n)[idx]).to(idx[Value(0)])" - ] - }, - { - "cell_type": "markdown", - "id": "81562baf-da04-4734-bc79-b0aedf11ab02", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Rules to compute shape and index into arange.\n" - ] - }, + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.run(1)\n", + "egraph" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "9283b1d4-f83d-4796-98b7-de1b4e5b2a67", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 33, - "id": "d46c1977-fa8c-4410-90c6-619ef3659a87", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___0_0\n", - "\n", - "\n", - "cluster_Values.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0:s->Values.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453:s->ten_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "10\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0\n", - "\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0\n", - "\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453\n", - "\n", - "\n", - "NDArray.shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0\n", - "\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ten_0\n", - "\n", - "\n", - "ten\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682\n", - "\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___0_0\n", - "\n", - "\n", - "cluster_Values.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0:s->Values.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453:s->ten_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "10\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0\n", - "\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0\n", - "\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453\n", - "\n", - "\n", - "NDArray.shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0\n", - "\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ten_0\n", - "\n", - "\n", - "ten\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682\n", - "\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[Module(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'arange': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()),), arg_names=('n',), arg_defaults=(None,), return_type=TypeRefWithVars(name='NDArray', args=()), var_arg_type=None)}, _classes={'Value': ClassDecl(methods={'__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), '__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('v',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0), 'Values': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'idx'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'length': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()),), arg_names=('self',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'concat': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Values', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='Vec', args=(TypeRefWithVars(name='Value', args=()),)),), arg_names=('v',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0), 'NDArray': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()), TypeRefWithVars(name='Values', args=())), arg_names=('self', 'idx'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'shape': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()),), arg_names=('self',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Value.__init__': {ClassMethodRef(class_name='Value', method_name='__init__')}, 'Value.__mul__': {MethodRef(class_name='Value', method_name='__mul__')}, 'Value.__add__': {MethodRef(class_name='Value', method_name='__add__')}, '!=': {MethodRef(class_name='NDArray', method_name='__ne__'), MethodRef(class_name='Values', method_name='__ne__'), MethodRef(class_name='Value', method_name='__ne__')}, 'Values.__init__': {ClassMethodRef(class_name='Values', method_name='__init__')}, 'Values.__getitem__': {MethodRef(class_name='Values', method_name='__getitem__')}, 'Values.length': {MethodRef(class_name='Values', method_name='length')}, 'Values.concat': {MethodRef(class_name='Values', method_name='concat')}, 'NDArray.__getitem__': {MethodRef(class_name='NDArray', method_name='__getitem__')}, 'NDArray.shape': {MethodRef(class_name='NDArray', method_name='shape')}, 'arange': {FunctionRef(name='arange')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Value', method_name='__init__'): 'Value.__init__', MethodRef(class_name='Value', method_name='__mul__'): 'Value.__mul__', MethodRef(class_name='Value', method_name='__add__'): 'Value.__add__', MethodRef(class_name='Value', method_name='__ne__'): '!=', ClassMethodRef(class_name='Values', method_name='__init__'): 'Values.__init__', MethodRef(class_name='Values', method_name='__getitem__'): 'Values.__getitem__', MethodRef(class_name='Values', method_name='length'): 'Values.length', MethodRef(class_name='Values', method_name='concat'): 'Values.concat', MethodRef(class_name='Values', method_name='__ne__'): '!=', MethodRef(class_name='NDArray', method_name='__getitem__'): 'NDArray.__getitem__', MethodRef(class_name='NDArray', method_name='shape'): 'NDArray.shape', MethodRef(class_name='NDArray', method_name='__ne__'): '!=', FunctionRef(name='arange'): 'arange'}, _egg_sort_to_type_ref={'Value': JustTypeRef(name='Value', args=()), 'Values': JustTypeRef(name='Values', args=()), 'Vec[Value]': JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)), 'NDArray': JustTypeRef(name='NDArray', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Value', args=()): 'Value', JustTypeRef(name='Values', args=()): 'Values', JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)): 'Vec[Value]', JustTypeRef(name='NDArray', args=()): 'NDArray'})))], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "Values(Vec.empty().push(Value(10)))" - ] - }, - "execution_count": 33, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph = EGraph([ndarray_mod])\n", - "ten = egraph.let(\"ten\", arange(Value(10)))\n", - "ten_shape = ten.shape()\n", - "egraph.register(ten_shape)\n", - "\n", - "egraph.run(20)\n", - "egraph.display()\n", - "egraph.extract(ten_shape)" - ] - }, - { - "cell_type": "code", - "execution_count": 34, - "id": "7a0d38d8-085a-4c61-ab23-06247c7171ef", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___0_0\n", - "\n", - "\n", - "cluster_Value.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "cluster_Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___0_0\n", - "\n", - "\n", - "cluster_Values.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906_0:s->NDArray.__getitem___11868447927124751835\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0:s->Values.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453:s->arange_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906:s->Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939:s->Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337:s->Values.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337:s->Value.__init___0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835:s->Values.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835:s->ten_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0:s->Value.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "10\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "7\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0\n", - "\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0\n", - "\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453\n", - "\n", - "\n", - "NDArray.shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906\n", - "\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0\n", - "\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ten_0\n", - "\n", - "\n", - "ten\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682\n", - "\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939\n", - "\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337\n", - "\n", - "\n", - "Values.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835\n", - "\n", - "\n", - "NDArray.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0\n", - "\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___0_0\n", - "\n", - "\n", - "cluster_Value.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "cluster_Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___0_0\n", - "\n", - "\n", - "cluster_Values.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906_0:s->NDArray.__getitem___11868447927124751835\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0:s->Values.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453:s->arange_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906:s->Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939:s->Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337:s->Values.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337:s->Value.__init___0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835:s->Values.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835:s->ten_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0:s->Value.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "10\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0_0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "7\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0\n", - "\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0\n", - "\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453\n", - "\n", - "\n", - "NDArray.shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906\n", - "\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0\n", - "\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ten_0\n", - "\n", - "\n", - "ten\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682\n", - "\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939\n", - "\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337\n", - "\n", - "\n", - "Values.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835\n", - "\n", - "\n", - "NDArray.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0\n", - "\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[Module(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'arange': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()),), arg_names=('n',), arg_defaults=(None,), return_type=TypeRefWithVars(name='NDArray', args=()), var_arg_type=None)}, _classes={'Value': ClassDecl(methods={'__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), '__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('v',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0), 'Values': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'idx'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'length': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()),), arg_names=('self',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'concat': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Values', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='Vec', args=(TypeRefWithVars(name='Value', args=()),)),), arg_names=('v',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0), 'NDArray': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()), TypeRefWithVars(name='Values', args=())), arg_names=('self', 'idx'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'shape': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()),), arg_names=('self',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Value.__init__': {ClassMethodRef(class_name='Value', method_name='__init__')}, 'Value.__mul__': {MethodRef(class_name='Value', method_name='__mul__')}, 'Value.__add__': {MethodRef(class_name='Value', method_name='__add__')}, '!=': {MethodRef(class_name='NDArray', method_name='__ne__'), MethodRef(class_name='Values', method_name='__ne__'), MethodRef(class_name='Value', method_name='__ne__')}, 'Values.__init__': {ClassMethodRef(class_name='Values', method_name='__init__')}, 'Values.__getitem__': {MethodRef(class_name='Values', method_name='__getitem__')}, 'Values.length': {MethodRef(class_name='Values', method_name='length')}, 'Values.concat': {MethodRef(class_name='Values', method_name='concat')}, 'NDArray.__getitem__': {MethodRef(class_name='NDArray', method_name='__getitem__')}, 'NDArray.shape': {MethodRef(class_name='NDArray', method_name='shape')}, 'arange': {FunctionRef(name='arange')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Value', method_name='__init__'): 'Value.__init__', MethodRef(class_name='Value', method_name='__mul__'): 'Value.__mul__', MethodRef(class_name='Value', method_name='__add__'): 'Value.__add__', MethodRef(class_name='Value', method_name='__ne__'): '!=', ClassMethodRef(class_name='Values', method_name='__init__'): 'Values.__init__', MethodRef(class_name='Values', method_name='__getitem__'): 'Values.__getitem__', MethodRef(class_name='Values', method_name='length'): 'Values.length', MethodRef(class_name='Values', method_name='concat'): 'Values.concat', MethodRef(class_name='Values', method_name='__ne__'): '!=', MethodRef(class_name='NDArray', method_name='__getitem__'): 'NDArray.__getitem__', MethodRef(class_name='NDArray', method_name='shape'): 'NDArray.shape', MethodRef(class_name='NDArray', method_name='__ne__'): '!=', FunctionRef(name='arange'): 'arange'}, _egg_sort_to_type_ref={'Value': JustTypeRef(name='Value', args=()), 'Values': JustTypeRef(name='Values', args=()), 'Vec[Value]': JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)), 'NDArray': JustTypeRef(name='NDArray', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Value', args=()): 'Value', JustTypeRef(name='Values', args=()): 'Values', JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)): 'Vec[Value]', JustTypeRef(name='NDArray', args=()): 'NDArray'})))], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'vec-empty': set(), 'Value.__init__': set(), 'vec-push': set(), 'Values.__init__': set()}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "Value(7)" - ] - }, - "execution_count": 34, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "ten_indexed = ten[Values(Vec(Value(7)))]\n", - "egraph.register(ten_indexed)\n", - "\n", - "egraph.run(20)\n", - "\n", - "egraph.display()\n", - "egraph.extract(ten_indexed)" - ] - }, - { - "cell_type": "markdown", - "id": "956f439e-80e6-4ff3-adb2-52a784ee5902", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Any user can try it now\n" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] - }, - { - "cell_type": "markdown", - "id": "07bece32-f436-4c6b-8d8a-21305673b376", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### 2. Someone else decides to implement a cross product library\n" - ] - }, - { - "cell_type": "code", - "execution_count": 35, - "id": "0eecf615-36c1-44a6-b122-743f66bc997f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "cross_mod = Module([ndarray_mod])\n", - "\n", - "\n", - "@cross_mod.function\n", - "def cross(l: NDArray, r: NDArray) -> NDArray:\n", - " ...\n", - "\n", - "\n", - "@cross_mod.register\n", - "def _cross(l: NDArray, r: NDArray, idx: Values):\n", - " yield rewrite(cross(l, r).shape()).to(l.shape().concat(r.shape()))\n", - " # Just noticed this is wrong!\n", - " yield rewrite(cross(l, r)[idx]).to(l[idx] * r[idx])" - ] - }, + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.run(1)\n", + "egraph" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "0aef5e81-43e3-4001-bf7a-b692fb3ff4b4", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "d1a60f2d-5669-4c05-be64-68f525eae9e4", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Someone decides to add some functionality\n", - "- Multiplicative cross product\n", - "- Shape is concatation, index is product of each matrix at that index\n", - "- Mathematical definition\n" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Num(3)\n" + ] }, { - "cell_type": "code", - "execution_count": 36, - "id": "a7127ee6-2d17-4460-942a-b303277d8f81", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Values(Vec.empty().push(Value(11)).push(Value(10)))" - ] - }, - "execution_count": 36, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph = EGraph([cross_mod])\n", - "egraph.simplify(cross(arange(Value(10)), arange(Value(11))).shape(), 10)" - ] - }, - { - "cell_type": "markdown", - "id": "944b5b6c-7583-4c75-a740-0d75a835c522", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### 3. I write my wonderful data science application using it\n" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "14fde972-d358-4324-bc1e-35b3591184cc", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Value(100)" - ] - }, - "execution_count": 37, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___0_0\n", + "\n", + "\n", + "cluster_Num.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0:s->Num.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408:s->fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453:s->Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978:s->fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__add___395596399104602408\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604:s->Num.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453_0\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___0\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___395596399104602408\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___5871781006564002453\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___16275225025205966978\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "f4_0\n", + "\n", + "\n", + "f4\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___5435976351651060604\n", + "\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "def my_special_app(x: Value) -> Value:\n", - " return cross(arange(x), arange(x))[Values(Vec(x))]\n", - "\n", - "\n", - "egraph = EGraph([cross_mod])\n", - "\n", - "egraph.simplify(my_special_app(Value(10)), 10)" - ] - }, - { - "cell_type": "markdown", - "id": "9f39ea1c-689d-4f5c-9fc3-bb8bd79e44f7", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Different person installs cross module\n", - "- Implements application using their complicated algorithm\n" - ] - }, - { - "cell_type": "markdown", - "id": "6967505c-48f0-45ad-837e-b6f2fdc99921", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - ".... but its too slow...\n" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'fib': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('x',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('i',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}, 'fib': {FunctionRef(name='fib')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__ne__'): '!=', FunctionRef(name='fib'): 'fib'}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] - }, - { - "cell_type": "code", - "execution_count": 38, - "id": "12a435f1-5059-43d0-8a22-001bcf2ce19f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "for i in range(100):\n", - " egraph.simplify(my_special_app(Value(i)), 10)" - ] - }, - { - "cell_type": "markdown", - "id": "06d04938-f7db-4094-a249-e778d199c3db", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Too slow in inner loop\n", - "- Is there a way we could optimize it\n" - ] - }, - { - "cell_type": "markdown", - "id": "8ba13f96-2333-43fd-a467-c18cf0daa9e4", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### 4. Someone else writes a library for delayed execution\n" - ] - }, + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.run(1)\n", + "print(egraph.extract(f4))\n", + "egraph" + ] + }, + { + "cell_type": "markdown", + "id": "a037bf31-2637-470a-ae26-b56538f689a6", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "### A story about Arrays\n" + ] + }, + { + "cell_type": "markdown", + "id": "082d9334-86e2-42a1-92f4-08563902b064", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- This is one path through a huge maze of use cases.\n", + "- Does not represent one killer example, but is an area I am familar with based on my previous work\n" + ] + }, + { + "cell_type": "markdown", + "id": "24955a1a-d3d6-44d8-a7ee-b5a87bd2a153", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "source": [ + "#### 1. Someone makes an NDArray library...\n" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "be2f1cb2-81c1-485d-8eb9-06c4d8b3c6ba", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "ndarray_mod = Module()" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "b0d83999-9aac-4881-a81a-385541b621fb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "@ndarray_mod.class_\n", + "class Value(Expr):\n", + " def __init__(self, v: i64Like) -> None: ...\n", + "\n", + " def __mul__(self, other: Value) -> Value: ...\n", + "\n", + " def __add__(self, other: Value) -> Value: ...\n", + "\n", + "\n", + "i, j = vars_(\"i j\", i64)\n", + "ndarray_mod.register(\n", + " rewrite(Value(i) * Value(j)).to(Value(i * j)),\n", + " rewrite(Value(i) + Value(j)).to(Value(i + j)),\n", + ")\n", + "\n", + "\n", + "@ndarray_mod.class_\n", + "class Values(Expr):\n", + " def __init__(self, v: Vec[Value]) -> None: ...\n", + "\n", + " def __getitem__(self, idx: Value) -> Value: ...\n", + "\n", + " def length(self) -> Value: ...\n", + "\n", + " def concat(self, other: Values) -> Values: ...\n", + "\n", + "\n", + "@ndarray_mod.register\n", + "def _values(vs: Vec[Value], other: Vec[Value]):\n", + " yield rewrite(Values(vs)[Value(i)]).to(vs[i])\n", + " yield rewrite(Values(vs).length()).to(Value(vs.length()))\n", + " yield rewrite(Values(vs).concat(Values(other))).to(Values(vs.append(other)))" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "0a9c6dfd-21b6-4e28-abe4-1bc8d8229a5a", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "@ndarray_mod.class_\n", + "class NDArray(Expr):\n", + " def __getitem__(self, idx: Values) -> Value: ...\n", + "\n", + " def shape(self) -> Values: ...\n", + "\n", + "\n", + "@ndarray_mod.function\n", + "def arange(n: Value) -> NDArray: ..." + ] + }, + { + "cell_type": "markdown", + "id": "36dd2603-c60e-42d0-a5d5-98043ed307a5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Basic\n", + "- One function, range, get shape and index into array\n", + "- Very different from existing paradigms in Python... Inheritance, multi-dispatch, dunder protocols.\n", + " - Entirely open protocol.\n", + " - Anyone else could define ways to create arrays\n", + " - About mathematical definition really. This is from M\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "0f36b591-9a20-4405-80cb-3dbfea11b129", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "Restifo Mullin, Lenore Marie, \"A mathematics of arrays\" (1988). _Electrical Engineering and Computer Science - Dissertations_. 249.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "3e020ae8-29a3-4e35-8510-aa2639c87701", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "@ndarray_mod.register\n", + "def _(n: Value, idx: Values, a: NDArray):\n", + " yield rewrite(arange(n).shape()).to(Values(Vec(n)))\n", + " yield rewrite(arange(n)[idx]).to(idx[Value(0)])" + ] + }, + { + "cell_type": "markdown", + "id": "81562baf-da04-4734-bc79-b0aedf11ab02", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Rules to compute shape and index into arange.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "d46c1977-fa8c-4410-90c6-619ef3659a87", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 39, - "id": "17e9ad75-f829-4a0c-bf8f-e9047cd0e177", - "metadata": { - "editable": true, - "scrolled": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Ellipsis" - ] - }, - "execution_count": 39, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___0_0\n", + "\n", + "\n", + "cluster_Values.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0:s->Values.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453:s->ten_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "10\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0\n", + "\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0\n", + "\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453\n", + "\n", + "\n", + "NDArray.shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0\n", + "\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ten_0\n", + "\n", + "\n", + "ten\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682\n", + "\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "py_mod = Module([ndarray_mod])\n", - "\n", - "\n", - "@py_mod.function\n", - "def py_value(s: StringLike) -> Value:\n", - " ...\n", - "\n", - "\n", - "..." - ] - }, - { - "cell_type": "markdown", - "id": "51cf4880-4576-40a7-8648-491218534d8f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- While this is happening, someone else, based on the original module, wrote a different execution semantics\n", - "- Builds up expression string instead of trying to evaluate eagerly\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "5ce8398b-ffac-4bc9-bb53-52c039f35093", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "@py_mod.register\n", - "def _py_value(l: String, r: String):\n", - " yield rewrite(py_value(l) + py_value(r)).to(py_value(join(l, \" + \", r)))\n", - " yield rewrite(py_value(l) * py_value(r)).to(py_value(join(l, \" * \", r)))\n", - "\n", - "\n", - "@py_mod.function\n", - "def py_values(s: StringLike) -> Values:\n", - " ...\n", - "\n", - "\n", - "@py_mod.register\n", - "def _py_values(l: String, r: String):\n", - " yield rewrite(py_values(l)[py_value(r)]).to(py_value(join(l, \"[\", r, \"]\")))\n", - " yield rewrite(py_values(l).length()).to(py_value(join(\"len(\", l, \")\")))\n", - " yield rewrite(py_values(l).concat(py_values(r))).to(py_values(join(l, \" + \", r)))\n", - "\n", - "\n", - "@py_mod.function\n", - "def py_ndarray(s: StringLike) -> NDArray:\n", - " ...\n", - "\n", - "\n", - "@py_mod.register\n", - "def _py_ndarray(l: String, r: String):\n", - " yield rewrite(py_ndarray(l)[py_values(r)]).to(py_value(join(l, \"[\", r, \"]\")))\n", - " yield rewrite(py_ndarray(l).shape()).to(py_values(join(l, \".shape\")))\n", - " yield rewrite(arange(py_value(l))).to(py_ndarray(join(\"np.arange(\", l, \")\")))" - ] - }, - { - "cell_type": "markdown", - "id": "85e7ceba-65f2-4766-8673-2d4dfa5bab96", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### 5. I can use it jit compile my application!\n" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "96bb493e-74a1-41a1-911e-a67ac31d92e5", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "py_value(\"x * x\")" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___0_0\n", + "\n", + "\n", + "cluster_Values.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0:s->Values.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453:s->ten_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "10\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0\n", + "\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0\n", + "\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453\n", + "\n", + "\n", + "NDArray.shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0\n", + "\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ten_0\n", + "\n", + "\n", + "ten\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682\n", + "\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph = EGraph([cross_mod, py_mod])\n", - "egraph.simplify(my_special_app(py_value(\"x\")), 10)" - ] - }, - { - "cell_type": "markdown", - "id": "5e9b8c74-42df-409c-ac74-66c605e46035", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- I pull in third party library\n", - "- Add it to my e-graph\n", - "- Now I can compile lazily\n", - "- py_mod never needed to know about cross product, works with it\n" + "text/plain": [ + "EGraph(_flatted_deps=[Module(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'arange': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()),), arg_names=('n',), arg_defaults=(None,), return_type=TypeRefWithVars(name='NDArray', args=()), var_arg_type=None)}, _classes={'Value': ClassDecl(methods={'__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), '__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('v',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0), 'Values': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'idx'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'length': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()),), arg_names=('self',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'concat': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Values', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='Vec', args=(TypeRefWithVars(name='Value', args=()),)),), arg_names=('v',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0), 'NDArray': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()), TypeRefWithVars(name='Values', args=())), arg_names=('self', 'idx'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'shape': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()),), arg_names=('self',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Value.__init__': {ClassMethodRef(class_name='Value', method_name='__init__')}, 'Value.__mul__': {MethodRef(class_name='Value', method_name='__mul__')}, 'Value.__add__': {MethodRef(class_name='Value', method_name='__add__')}, '!=': {MethodRef(class_name='NDArray', method_name='__ne__'), MethodRef(class_name='Values', method_name='__ne__'), MethodRef(class_name='Value', method_name='__ne__')}, 'Values.__init__': {ClassMethodRef(class_name='Values', method_name='__init__')}, 'Values.__getitem__': {MethodRef(class_name='Values', method_name='__getitem__')}, 'Values.length': {MethodRef(class_name='Values', method_name='length')}, 'Values.concat': {MethodRef(class_name='Values', method_name='concat')}, 'NDArray.__getitem__': {MethodRef(class_name='NDArray', method_name='__getitem__')}, 'NDArray.shape': {MethodRef(class_name='NDArray', method_name='shape')}, 'arange': {FunctionRef(name='arange')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Value', method_name='__init__'): 'Value.__init__', MethodRef(class_name='Value', method_name='__mul__'): 'Value.__mul__', MethodRef(class_name='Value', method_name='__add__'): 'Value.__add__', MethodRef(class_name='Value', method_name='__ne__'): '!=', ClassMethodRef(class_name='Values', method_name='__init__'): 'Values.__init__', MethodRef(class_name='Values', method_name='__getitem__'): 'Values.__getitem__', MethodRef(class_name='Values', method_name='length'): 'Values.length', MethodRef(class_name='Values', method_name='concat'): 'Values.concat', MethodRef(class_name='Values', method_name='__ne__'): '!=', MethodRef(class_name='NDArray', method_name='__getitem__'): 'NDArray.__getitem__', MethodRef(class_name='NDArray', method_name='shape'): 'NDArray.shape', MethodRef(class_name='NDArray', method_name='__ne__'): '!=', FunctionRef(name='arange'): 'arange'}, _egg_sort_to_type_ref={'Value': JustTypeRef(name='Value', args=()), 'Values': JustTypeRef(name='Values', args=()), 'Vec[Value]': JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)), 'NDArray': JustTypeRef(name='NDArray', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Value', args=()): 'Value', JustTypeRef(name='Values', args=()): 'Values', JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)): 'Vec[Value]', JustTypeRef(name='NDArray', args=()): 'NDArray'})))], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "id": "b5abc145-33bf-4093-ae7d-5dd4a60bc6ae", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "... and add support for jit compilation for the other library I am using, without changing either library:\n" + "data": { + "text/plain": [ + "Values(Vec.empty().push(Value(10)))" ] - }, + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph([ndarray_mod])\n", + "ten = egraph.let(\"ten\", arange(Value(10)))\n", + "ten_shape = ten.shape()\n", + "egraph.register(ten_shape)\n", + "\n", + "egraph.run(20)\n", + "egraph.display()\n", + "egraph.extract(ten_shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "7a0d38d8-085a-4c61-ab23-06247c7171ef", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 42, - "id": "14cec5ba-b96e-46ef-853a-ddbe4ccfb37f", - "metadata": { - "collapsed": true, - "editable": true, - "jupyter": { - "outputs_hidden": true - }, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [ - { - "ename": "KeyError", - "evalue": "\"Callable ref FunctionRef(name='py_ndarray') not found\"", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[42], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;129;43m@egraph\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mregister\u001b[49m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;43;01mdef\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;21;43m_\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43ml\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mString\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mr\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mString\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrewrite\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcross\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpy_ndarray\u001b[49m\u001b[43m(\u001b[49m\u001b[43ml\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpy_ndarray\u001b[49m\u001b[43m(\u001b[49m\u001b[43mr\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpy_ndarray\u001b[49m\u001b[43m(\u001b[49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mnp.multiply.outer(\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43ml\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m, \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mr\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m)\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:507\u001b[0m, in \u001b[0;36m_BaseModule.register\u001b[0;34m(self, command_or_generator, *commands)\u001b[0m\n\u001b[1;32m 505\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 506\u001b[0m commands \u001b[38;5;241m=\u001b[39m (cast(CommandLike, command_or_generator), \u001b[38;5;241m*\u001b[39mcommands)\n\u001b[0;32m--> 507\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_process_commands\u001b[49m\u001b[43m(\u001b[49m\u001b[43m_command_like\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcommand\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_to_egg_command\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mcommand\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mcommands\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:634\u001b[0m, in \u001b[0;36mEGraph._process_commands\u001b[0;34m(self, commands)\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_process_commands\u001b[39m(\u001b[38;5;28mself\u001b[39m, commands: Iterable[bindings\u001b[38;5;241m.\u001b[39m_Command]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 634\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_egraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_program\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcommands\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:507\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 505\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 506\u001b[0m commands \u001b[38;5;241m=\u001b[39m (cast(CommandLike, command_or_generator), \u001b[38;5;241m*\u001b[39mcommands)\n\u001b[0;32m--> 507\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_process_commands(\u001b[43m_command_like\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcommand\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_to_egg_command\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m command \u001b[38;5;129;01min\u001b[39;00m commands)\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:907\u001b[0m, in \u001b[0;36mRewrite._to_egg_command\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 906\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_to_egg_command\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39m_Command:\n\u001b[0;32m--> 907\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mRewriteCommand(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ruleset, \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_to_egg_rewrite\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m)\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:911\u001b[0m, in \u001b[0;36mRewrite._to_egg_rewrite\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 909\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_to_egg_rewrite\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39mRewrite:\n\u001b[1;32m 910\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mRewrite(\n\u001b[0;32m--> 911\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_lhs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__to_egg__\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m 912\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_rhs\u001b[38;5;241m.\u001b[39m__to_egg__(),\n\u001b[1;32m 913\u001b[0m [c\u001b[38;5;241m.\u001b[39m_to_egg_fact() \u001b[38;5;28;01mfor\u001b[39;00m c \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_conditions],\n\u001b[1;32m 914\u001b[0m )\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/runtime.py:370\u001b[0m, in \u001b[0;36mRuntimeExpr.__to_egg__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 369\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__to_egg__\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39m_Expr:\n\u001b[0;32m--> 370\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__egg_typed_expr__\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexpr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto_egg\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__egg_decls__\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:582\u001b[0m, in \u001b[0;36mCallDecl.to_egg\u001b[0;34m(self, mod_decls)\u001b[0m\n\u001b[1;32m 580\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Convert a Call to an egg Call.\"\"\"\u001b[39;00m\n\u001b[1;32m 581\u001b[0m egg_fn \u001b[38;5;241m=\u001b[39m mod_decls\u001b[38;5;241m.\u001b[39mget_egg_fn(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcallable)\n\u001b[0;32m--> 582\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mCall(egg_fn, [a\u001b[38;5;241m.\u001b[39mto_egg(mod_decls) \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs])\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:582\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 580\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Convert a Call to an egg Call.\"\"\"\u001b[39;00m\n\u001b[1;32m 581\u001b[0m egg_fn \u001b[38;5;241m=\u001b[39m mod_decls\u001b[38;5;241m.\u001b[39mget_egg_fn(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcallable)\n\u001b[0;32m--> 582\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mCall(egg_fn, [\u001b[43ma\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto_egg\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmod_decls\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs])\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:681\u001b[0m, in \u001b[0;36mTypedExprDecl.to_egg\u001b[0;34m(self, decls)\u001b[0m\n\u001b[1;32m 680\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mto_egg\u001b[39m(\u001b[38;5;28mself\u001b[39m, decls: ModuleDeclarations) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39m_Expr:\n\u001b[0;32m--> 681\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexpr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto_egg\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecls\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:581\u001b[0m, in \u001b[0;36mCallDecl.to_egg\u001b[0;34m(self, mod_decls)\u001b[0m\n\u001b[1;32m 579\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mto_egg\u001b[39m(\u001b[38;5;28mself\u001b[39m, mod_decls: ModuleDeclarations) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39mCall:\n\u001b[1;32m 580\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Convert a Call to an egg Call.\"\"\"\u001b[39;00m\n\u001b[0;32m--> 581\u001b[0m egg_fn \u001b[38;5;241m=\u001b[39m \u001b[43mmod_decls\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_egg_fn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcallable\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 582\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mCall(egg_fn, [a\u001b[38;5;241m.\u001b[39mto_egg(mod_decls) \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs])\n", - "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:205\u001b[0m, in \u001b[0;36mModuleDeclarations.get_egg_fn\u001b[0;34m(self, ref)\u001b[0m\n\u001b[1;32m 203\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m:\n\u001b[1;32m 204\u001b[0m \u001b[38;5;28;01mpass\u001b[39;00m\n\u001b[0;32m--> 205\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCallable ref \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mref\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m not found\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", - "\u001b[0;31mKeyError\u001b[0m: \"Callable ref FunctionRef(name='py_ndarray') not found\"" - ] - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___0_0\n", + "\n", + "\n", + "cluster_Value.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "cluster_Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___0_0\n", + "\n", + "\n", + "cluster_Values.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906_0:s->NDArray.__getitem___11868447927124751835\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0:s->Values.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453:s->arange_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906:s->Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939:s->Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337:s->Values.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337:s->Value.__init___0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835:s->Values.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835:s->ten_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0:s->Value.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "10\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0\n", + "\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0\n", + "\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453\n", + "\n", + "\n", + "NDArray.shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906\n", + "\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0\n", + "\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ten_0\n", + "\n", + "\n", + "ten\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682\n", + "\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939\n", + "\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337\n", + "\n", + "\n", + "Values.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835\n", + "\n", + "\n", + "NDArray.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0\n", + "\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "@egraph.register\n", - "def _(l: String, r: String):\n", - " yield rewrite(cross(py_ndarray(l), py_ndarray(r))).to(\n", - " py_ndarray(join(\"np.multiply.outer(\", l, \", \", r, \")\"))\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "10190128-8d45-4722-8977-4855a0e44be9", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "egraph.run(20)\n", - "egraph.graphviz().render(outfile=\"big_graph.svg\", format=\"svg\")" - ] - }, - { - "cell_type": "markdown", - "id": "193b6cf7-01b1-4446-8664-04d622fb0070", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### Takeaways...\n", - "\n", - "_...from this totally realistic example._\n", - "\n", - "- Declerative nature of `egglog` could facilitate decentralized library collaboration and experimentation.\n", - " - Focus on types over values for library authors encourages interoperability.\n", - "- Pushing power down, empowering users and library authors\n", - "- Could allow greater collaboration between PL community and data science library community in Python\n" - ] - }, - { - "cell_type": "markdown", - "id": "8ff417fb-cad6-491d-914d-bc8d8cb6880e", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Arrays in the \"Real World\"\n", - "\n", - "What would it take to make this example work with `egglog`?\n" - ] - }, - { - "cell_type": "code", - "execution_count": 43, - "id": "e0746462-4f02-4119-a28f-dc10e1f9e124", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 8.06179978, -0.30042062],\n", - " [ 7.12868772, 0.78666043],\n", - " [ 7.48982797, 0.26538449],\n", - " [ 6.81320057, 0.67063107],\n", - " [ 8.13230933, -0.51446253]])" - ] - }, - "execution_count": 43, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___0_0\n", + "\n", + "\n", + "cluster_Value.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "cluster_Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___0_0\n", + "\n", + "\n", + "cluster_Values.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906_0:s->NDArray.__getitem___11868447927124751835\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0:s->Values.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453:s->arange_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906:s->Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939:s->Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337:s->Values.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337:s->Value.__init___0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835:s->Values.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835:s->ten_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0:s->Value.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "10\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0_0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0\n", + "\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0\n", + "\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453\n", + "\n", + "\n", + "NDArray.shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906\n", + "\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0\n", + "\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ten_0\n", + "\n", + "\n", + "ten\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682\n", + "\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939\n", + "\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337\n", + "\n", + "\n", + "Values.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835\n", + "\n", + "\n", + "NDArray.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0\n", + "\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "from sklearn import datasets\n", - "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n", - "from sklearn import config_context\n", - "\n", - "iris = datasets.load_iris()\n", - "\n", - "X = iris.data\n", - "y = iris.target\n", - "\n", - "\n", - "def fit(X, y):\n", - " with config_context(array_api_dispatch=True):\n", - " lda = LinearDiscriminantAnalysis(n_components=2)\n", - " X_r2 = lda.fit(X, y).transform(X)\n", - " return X_r2\n", - "\n", - "\n", - "fit(X, y)[:5]" + "text/plain": [ + "EGraph(_flatted_deps=[Module(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'arange': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()),), arg_names=('n',), arg_defaults=(None,), return_type=TypeRefWithVars(name='NDArray', args=()), var_arg_type=None)}, _classes={'Value': ClassDecl(methods={'__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), '__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), arg_names=('v',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0), 'Values': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Value', args=())), arg_names=('self', 'idx'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'length': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()),), arg_names=('self',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'concat': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Values', args=())), arg_names=('self', 'other'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='Vec', args=(TypeRefWithVars(name='Value', args=()),)),), arg_names=('v',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0), 'NDArray': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()), TypeRefWithVars(name='Values', args=())), arg_names=('self', 'idx'), arg_defaults=(None, None), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'shape': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()),), arg_names=('self',), arg_defaults=(None,), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={}, class_variables={}, properties={}, preserved_methods={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Value.__init__': {ClassMethodRef(class_name='Value', method_name='__init__')}, 'Value.__mul__': {MethodRef(class_name='Value', method_name='__mul__')}, 'Value.__add__': {MethodRef(class_name='Value', method_name='__add__')}, '!=': {MethodRef(class_name='NDArray', method_name='__ne__'), MethodRef(class_name='Values', method_name='__ne__'), MethodRef(class_name='Value', method_name='__ne__')}, 'Values.__init__': {ClassMethodRef(class_name='Values', method_name='__init__')}, 'Values.__getitem__': {MethodRef(class_name='Values', method_name='__getitem__')}, 'Values.length': {MethodRef(class_name='Values', method_name='length')}, 'Values.concat': {MethodRef(class_name='Values', method_name='concat')}, 'NDArray.__getitem__': {MethodRef(class_name='NDArray', method_name='__getitem__')}, 'NDArray.shape': {MethodRef(class_name='NDArray', method_name='shape')}, 'arange': {FunctionRef(name='arange')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Value', method_name='__init__'): 'Value.__init__', MethodRef(class_name='Value', method_name='__mul__'): 'Value.__mul__', MethodRef(class_name='Value', method_name='__add__'): 'Value.__add__', MethodRef(class_name='Value', method_name='__ne__'): '!=', ClassMethodRef(class_name='Values', method_name='__init__'): 'Values.__init__', MethodRef(class_name='Values', method_name='__getitem__'): 'Values.__getitem__', MethodRef(class_name='Values', method_name='length'): 'Values.length', MethodRef(class_name='Values', method_name='concat'): 'Values.concat', MethodRef(class_name='Values', method_name='__ne__'): '!=', MethodRef(class_name='NDArray', method_name='__getitem__'): 'NDArray.__getitem__', MethodRef(class_name='NDArray', method_name='shape'): 'NDArray.shape', MethodRef(class_name='NDArray', method_name='__ne__'): '!=', FunctionRef(name='arange'): 'arange'}, _egg_sort_to_type_ref={'Value': JustTypeRef(name='Value', args=()), 'Values': JustTypeRef(name='Values', args=()), 'Vec[Value]': JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)), 'NDArray': JustTypeRef(name='NDArray', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Value', args=()): 'Value', JustTypeRef(name='Values', args=()): 'Values', JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)): 'Vec[Value]', JustTypeRef(name='NDArray', args=()): 'NDArray'})))], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'vec-empty': set(), 'Value.__init__': set(), 'vec-push': set(), 'Values.__init__': set()}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "id": "de801623-8f64-450e-b6bf-4e53e2bdcbe6", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "Could we execute this symbolically?\n", - "\n", - "```python\n", - "@egraph.class_\n", - "class NDArray(Expr):\n", - " @classmethod\n", - " def var(cls, name: StringLike) -> NDArray:\n", - " ...\n", - "\n", - " ...\n", - "X_arr = NDArray.var(\"X\")\n", - "y_arr = NDArray.var(\"y\")\n", - "fit(X_arr, y_arr)\n", - "```\n", - "\n", - "Started working on this yesterday...\n" + "data": { + "text/plain": [ + "Value(7)" ] - }, + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ten_indexed = ten[Values(Vec(Value(7)))]\n", + "egraph.register(ten_indexed)\n", + "\n", + "egraph.run(20)\n", + "\n", + "egraph.display()\n", + "egraph.extract(ten_indexed)" + ] + }, + { + "cell_type": "markdown", + "id": "956f439e-80e6-4ff3-adb2-52a784ee5902", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Any user can try it now\n" + ] + }, + { + "cell_type": "markdown", + "id": "07bece32-f436-4c6b-8d8a-21305673b376", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "#### 2. Someone else decides to implement a cross product library\n" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "0eecf615-36c1-44a6-b122-743f66bc997f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "cross_mod = Module([ndarray_mod])\n", + "\n", + "\n", + "@cross_mod.function\n", + "def cross(l: NDArray, r: NDArray) -> NDArray: ...\n", + "\n", + "\n", + "@cross_mod.register\n", + "def _cross(l: NDArray, r: NDArray, idx: Values):\n", + " yield rewrite(cross(l, r).shape()).to(l.shape().concat(r.shape()))\n", + " # Just noticed this is wrong!\n", + " yield rewrite(cross(l, r)[idx]).to(l[idx] * r[idx])" + ] + }, + { + "cell_type": "markdown", + "id": "d1a60f2d-5669-4c05-be64-68f525eae9e4", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Someone decides to add some functionality\n", + "- Multiplicative cross product\n", + "- Shape is concatation, index is product of each matrix at that index\n", + "- Mathematical definition\n" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "a7127ee6-2d17-4460-942a-b303277d8f81", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "20078da0-a583-414a-853c-0a8a410ce5ff", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "Provide egglog with metadata at least about the types, to get through sklearn's sanity checks (which need to be executed eagerly):\n", - "\n", - "```python\n", - "egraph.register(\n", - " rewrite(X_arr.dtype).to(convert(X.dtype, DType)),\n", - " rewrite(y_arr.dtype).to(convert(y.dtype, DType)),\n", - " rewrite(isfinite(sum(X_arr)).bool()).to(TRUE),\n", - " rewrite(isfinite(sum(y_arr)).bool()).to(TRUE),\n", - " rewrite(X_arr.shape).to(convert(X.shape, TupleInt)),\n", - " rewrite(y_arr.shape).to(convert(y.shape, TupleInt)),\n", - " rewrite(X_arr.size).to(Int(X.size)),\n", - " rewrite(y_arr.size).to(Int(y.size)),\n", - " rewrite(unique_values(y_arr).shape).to(TupleInt(Int(3)))\n", - ")\n", - "```\n" + "data": { + "text/plain": [ + "Values(Vec.empty().push(Value(11)).push(Value(10)))" ] - }, + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph([cross_mod])\n", + "egraph.simplify(cross(arange(Value(10)), arange(Value(11))).shape(), 10)" + ] + }, + { + "cell_type": "markdown", + "id": "944b5b6c-7583-4c75-a740-0d75a835c522", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "#### 3. I write my wonderful data science application using it\n" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "14fde972-d358-4324-bc1e-35b3591184cc", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "85112e88-b0e7-4cb3-b3fd-7365fb95f16f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "source": [ - "Define all the required Array API functions:\n", - "\n", - "```python\n", - "@egraph.function\n", - "def reshape(x: NDArray, shape: TupleInt, copy: OptionalBool = OptionalBool.none) -> NDArray:\n", - " ...\n", - "```\n" + "data": { + "text/plain": [ + "Value(100)" ] - }, + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def my_special_app(x: Value) -> Value:\n", + " return cross(arange(x), arange(x))[Values(Vec(x))]\n", + "\n", + "\n", + "egraph = EGraph([cross_mod])\n", + "\n", + "egraph.simplify(my_special_app(Value(10)), 10)" + ] + }, + { + "cell_type": "markdown", + "id": "9f39ea1c-689d-4f5c-9fc3-bb8bd79e44f7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Different person installs cross module\n", + "- Implements application using their complicated algorithm\n" + ] + }, + { + "cell_type": "markdown", + "id": "6967505c-48f0-45ad-837e-b6f2fdc99921", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + ".... but its too slow...\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "12a435f1-5059-43d0-8a22-001bcf2ce19f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "for i in range(100):\n", + " egraph.simplify(my_special_app(Value(i)), 10)" + ] + }, + { + "cell_type": "markdown", + "id": "06d04938-f7db-4094-a249-e778d199c3db", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Too slow in inner loop\n", + "- Is there a way we could optimize it\n" + ] + }, + { + "cell_type": "markdown", + "id": "8ba13f96-2333-43fd-a467-c18cf0daa9e4", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "#### 4. Someone else writes a library for delayed execution\n" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "17e9ad75-f829-4a0c-bf8f-e9047cd0e177", + "metadata": { + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "4d36583e-69b0-4698-9792-99799d261782", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "```python\n", - "@egraph.register\n", - "def _reshape(x: NDArray, y: NDArray, shape: TupleInt, copy: OptionalBool, i: Int, s: String):\n", - " return [\n", - " # dtype of result is same as input\n", - " rewrite(\n", - " reshape(x, shape, copy).dtype\n", - " ).to(x.dtype),\n", - " # dimensions of output are the same as length of shape\n", - " rewrite(\n", - " reshape(x, shape, copy).shape.length()\n", - " ).to(shape.length()),\n", - " # Shape of single dimensions reshape is the # elements\n", - " rewrite(\n", - " reshape(x, TupleInt(Int(-1)), copy).shape\n", - " ).to(TupleInt(x.size)),\n", - " # Reshaping one dimension no-op\n", - " rule(\n", - " eq(y).to(reshape(x, TupleInt(Int(-1)), copy)),\n", - " eq(x.shape).to(TupleInt(i)),\n", - " ).then(\n", - " union(x).with_(y)\n", - " )\n", - " ]\n", - "```\n" + "data": { + "text/plain": [ + "Ellipsis" ] - }, + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "py_mod = Module([ndarray_mod])\n", + "\n", + "\n", + "@py_mod.function\n", + "def py_value(s: StringLike) -> Value: ..." + ] + }, + { + "cell_type": "markdown", + "id": "51cf4880-4576-40a7-8648-491218534d8f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- While this is happening, someone else, based on the original module, wrote a different execution semantics\n", + "- Builds up expression string instead of trying to evaluate eagerly\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ce8398b-ffac-4bc9-bb53-52c039f35093", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "@py_mod.register\n", + "def _py_value(l: String, r: String):\n", + " yield rewrite(py_value(l) + py_value(r)).to(py_value(join(l, \" + \", r)))\n", + " yield rewrite(py_value(l) * py_value(r)).to(py_value(join(l, \" * \", r)))\n", + "\n", + "\n", + "@py_mod.function\n", + "def py_values(s: StringLike) -> Values: ...\n", + "\n", + "\n", + "@py_mod.register\n", + "def _py_values(l: String, r: String):\n", + " yield rewrite(py_values(l)[py_value(r)]).to(py_value(join(l, \"[\", r, \"]\")))\n", + " yield rewrite(py_values(l).length()).to(py_value(join(\"len(\", l, \")\")))\n", + " yield rewrite(py_values(l).concat(py_values(r))).to(py_values(join(l, \" + \", r)))\n", + "\n", + "\n", + "@py_mod.function\n", + "def py_ndarray(s: StringLike) -> NDArray: ...\n", + "\n", + "\n", + "@py_mod.register\n", + "def _py_ndarray(l: String, r: String):\n", + " yield rewrite(py_ndarray(l)[py_values(r)]).to(py_value(join(l, \"[\", r, \"]\")))\n", + " yield rewrite(py_ndarray(l).shape()).to(py_values(join(l, \".shape\")))\n", + " yield rewrite(arange(py_value(l))).to(py_ndarray(join(\"np.arange(\", l, \")\")))" + ] + }, + { + "cell_type": "markdown", + "id": "85e7ceba-65f2-4766-8673-2d4dfa5bab96", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "#### 5. I can use it jit compile my application!\n" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "96bb493e-74a1-41a1-911e-a67ac31d92e5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "bc1cf64c-f7bf-4ebb-ae55-1b74ea6d795e", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "Can see some examples of rewrites executing during sklearns checking:\n", - "\n", - "```python\n", - "asarray(reshape(asarray(NDArray.var(\"y\")), (TupleInt(Int(-1)) + TupleInt.EMPTY))).shape[Int(0)] == asarray(NDArray.var(\"X\")).shape[Int(0)]\n", - " -> NDArray.var(\"y\").size == NDArray.var(\"X\").shape[Int(0)]\n", - " -> TRUE\n", - "\n", - "asarray(asarray(reshape(asarray(NDArray.var(\"y\")), (TupleInt(Int(-1)) + TupleInt.EMPTY)))).ndim == Int(2)\n", - " -> FALSE\n", - "```\n" + "data": { + "text/plain": [ + "py_value(\"x * x\")" ] - }, + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph([cross_mod, py_mod])\n", + "egraph.simplify(my_special_app(py_value(\"x\")), 10)" + ] + }, + { + "cell_type": "markdown", + "id": "5e9b8c74-42df-409c-ac74-66c605e46035", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- I pull in third party library\n", + "- Add it to my e-graph\n", + "- Now I can compile lazily\n", + "- py_mod never needed to know about cross product, works with it\n" + ] + }, + { + "cell_type": "markdown", + "id": "b5abc145-33bf-4093-ae7d-5dd4a60bc6ae", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "source": [ + "... and add support for jit compilation for the other library I am using, without changing either library:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "14cec5ba-b96e-46ef-853a-ddbe4ccfb37f", + "metadata": { + "collapsed": true, + "editable": true, + "jupyter": { + "outputs_hidden": true + }, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "ddf19e72-5204-41f8-860e-cf45dfc0fc20", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "That's as far as I got!\n" - ] - }, + "ename": "KeyError", + "evalue": "\"Callable ref FunctionRef(name='py_ndarray') not found\"", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[42], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;129;43m@egraph\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mregister\u001b[49m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;43;01mdef\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;21;43m_\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43ml\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mString\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mr\u001b[49m\u001b[43m:\u001b[49m\u001b[43m \u001b[49m\u001b[43mString\u001b[49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[1;32m 3\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrewrite\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcross\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpy_ndarray\u001b[49m\u001b[43m(\u001b[49m\u001b[43ml\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpy_ndarray\u001b[49m\u001b[43m(\u001b[49m\u001b[43mr\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpy_ndarray\u001b[49m\u001b[43m(\u001b[49m\u001b[43mjoin\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mnp.multiply.outer(\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43ml\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m, \u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mr\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m)\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:507\u001b[0m, in \u001b[0;36m_BaseModule.register\u001b[0;34m(self, command_or_generator, *commands)\u001b[0m\n\u001b[1;32m 505\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 506\u001b[0m commands \u001b[38;5;241m=\u001b[39m (cast(CommandLike, command_or_generator), \u001b[38;5;241m*\u001b[39mcommands)\n\u001b[0;32m--> 507\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_process_commands\u001b[49m\u001b[43m(\u001b[49m\u001b[43m_command_like\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcommand\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_to_egg_command\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mcommand\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mcommands\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:634\u001b[0m, in \u001b[0;36mEGraph._process_commands\u001b[0;34m(self, commands)\u001b[0m\n\u001b[1;32m 633\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_process_commands\u001b[39m(\u001b[38;5;28mself\u001b[39m, commands: Iterable[bindings\u001b[38;5;241m.\u001b[39m_Command]) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m--> 634\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_egraph\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun_program\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mcommands\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:507\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 505\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 506\u001b[0m commands \u001b[38;5;241m=\u001b[39m (cast(CommandLike, command_or_generator), \u001b[38;5;241m*\u001b[39mcommands)\n\u001b[0;32m--> 507\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_process_commands(\u001b[43m_command_like\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcommand\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_to_egg_command\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m command \u001b[38;5;129;01min\u001b[39;00m commands)\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:907\u001b[0m, in \u001b[0;36mRewrite._to_egg_command\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 906\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_to_egg_command\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39m_Command:\n\u001b[0;32m--> 907\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mRewriteCommand(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_ruleset, \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_to_egg_rewrite\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m)\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/egraph.py:911\u001b[0m, in \u001b[0;36mRewrite._to_egg_rewrite\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 909\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_to_egg_rewrite\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39mRewrite:\n\u001b[1;32m 910\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mRewrite(\n\u001b[0;32m--> 911\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_lhs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__to_egg__\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m,\n\u001b[1;32m 912\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_rhs\u001b[38;5;241m.\u001b[39m__to_egg__(),\n\u001b[1;32m 913\u001b[0m [c\u001b[38;5;241m.\u001b[39m_to_egg_fact() \u001b[38;5;28;01mfor\u001b[39;00m c \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_conditions],\n\u001b[1;32m 914\u001b[0m )\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/runtime.py:370\u001b[0m, in \u001b[0;36mRuntimeExpr.__to_egg__\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 369\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__to_egg__\u001b[39m(\u001b[38;5;28mself\u001b[39m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39m_Expr:\n\u001b[0;32m--> 370\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__egg_typed_expr__\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexpr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto_egg\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__egg_decls__\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:582\u001b[0m, in \u001b[0;36mCallDecl.to_egg\u001b[0;34m(self, mod_decls)\u001b[0m\n\u001b[1;32m 580\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Convert a Call to an egg Call.\"\"\"\u001b[39;00m\n\u001b[1;32m 581\u001b[0m egg_fn \u001b[38;5;241m=\u001b[39m mod_decls\u001b[38;5;241m.\u001b[39mget_egg_fn(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcallable)\n\u001b[0;32m--> 582\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mCall(egg_fn, [a\u001b[38;5;241m.\u001b[39mto_egg(mod_decls) \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs])\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:582\u001b[0m, in \u001b[0;36m\u001b[0;34m(.0)\u001b[0m\n\u001b[1;32m 580\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Convert a Call to an egg Call.\"\"\"\u001b[39;00m\n\u001b[1;32m 581\u001b[0m egg_fn \u001b[38;5;241m=\u001b[39m mod_decls\u001b[38;5;241m.\u001b[39mget_egg_fn(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcallable)\n\u001b[0;32m--> 582\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mCall(egg_fn, [\u001b[43ma\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto_egg\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmod_decls\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs])\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:681\u001b[0m, in \u001b[0;36mTypedExprDecl.to_egg\u001b[0;34m(self, decls)\u001b[0m\n\u001b[1;32m 680\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mto_egg\u001b[39m(\u001b[38;5;28mself\u001b[39m, decls: ModuleDeclarations) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39m_Expr:\n\u001b[0;32m--> 681\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexpr\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto_egg\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdecls\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:581\u001b[0m, in \u001b[0;36mCallDecl.to_egg\u001b[0;34m(self, mod_decls)\u001b[0m\n\u001b[1;32m 579\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mto_egg\u001b[39m(\u001b[38;5;28mself\u001b[39m, mod_decls: ModuleDeclarations) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m bindings\u001b[38;5;241m.\u001b[39mCall:\n\u001b[1;32m 580\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Convert a Call to an egg Call.\"\"\"\u001b[39;00m\n\u001b[0;32m--> 581\u001b[0m egg_fn \u001b[38;5;241m=\u001b[39m \u001b[43mmod_decls\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_egg_fn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcallable\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 582\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m bindings\u001b[38;5;241m.\u001b[39mCall(egg_fn, [a\u001b[38;5;241m.\u001b[39mto_egg(mod_decls) \u001b[38;5;28;01mfor\u001b[39;00m a \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39margs])\n", + "File \u001b[0;32m~/p/egg-smol-python/python/egglog/declarations.py:205\u001b[0m, in \u001b[0;36mModuleDeclarations.get_egg_fn\u001b[0;34m(self, ref)\u001b[0m\n\u001b[1;32m 203\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m:\n\u001b[1;32m 204\u001b[0m \u001b[38;5;28;01mpass\u001b[39;00m\n\u001b[0;32m--> 205\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mKeyError\u001b[39;00m(\u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mCallable ref \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mref\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m not found\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "\u001b[0;31mKeyError\u001b[0m: \"Callable ref FunctionRef(name='py_ndarray') not found\"" + ] + } + ], + "source": [ + "@egraph.register\n", + "def _(l: String, r: String):\n", + " yield rewrite(cross(py_ndarray(l), py_ndarray(r))).to(py_ndarray(join(\"np.multiply.outer(\", l, \", \", r, \")\")))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "10190128-8d45-4722-8977-4855a0e44be9", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" + }, + "tags": [] + }, + "outputs": [], + "source": [ + "egraph.run(20)\n", + "egraph.graphviz().render(outfile=\"big_graph.svg\", format=\"svg\")" + ] + }, + { + "cell_type": "markdown", + "id": "193b6cf7-01b1-4446-8664-04d622fb0070", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "#### Takeaways...\n", + "\n", + "_...from this totally realistic example._\n", + "\n", + "- Declerative nature of `egglog` could facilitate decentralized library collaboration and experimentation.\n", + " - Focus on types over values for library authors encourages interoperability.\n", + "- Pushing power down, empowering users and library authors\n", + "- Could allow greater collaboration between PL community and data science library community in Python\n" + ] + }, + { + "cell_type": "markdown", + "id": "8ff417fb-cad6-491d-914d-bc8d8cb6880e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## Arrays in the \"Real World\"\n", + "\n", + "What would it take to make this example work with `egglog`?\n" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "id": "e0746462-4f02-4119-a28f-dc10e1f9e124", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "2b67e0b8-3c8d-45a5-a041-4293da7aed9e", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Conclusion\n", - "\n", - "- e-graphs are a data structure we can use to build term rewriting systems\n", - "- `egglog` is a language, and Python library, for building e-graphs\n", - "- Looking forward to seeing how it might be used in PyData ecosystem\n", - "\n", - "```bash\n", - "pip install egglog\n", - "```\n", - "\n", - "Welcome new contributations, experiments, and conversations...\n", - "\n", - "_Come say hello at [github.com/egraphs-good/egglog-python](https://github.com/egraphs-good/egglog-python) ad [egraphs.zulipchat.com](https://egraphs.zulipchat.com/)!_\n" + "data": { + "text/plain": [ + "array([[ 8.06179978, -0.30042062],\n", + " [ 7.12868772, 0.78666043],\n", + " [ 7.48982797, 0.26538449],\n", + " [ 6.81320057, 0.67063107],\n", + " [ 8.13230933, -0.51446253]])" ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8a7fea36-c3f8-4fc2-970b-98ad2f439387", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "" - }, - "tags": [] - }, - "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.10.12" - }, - "mystnb": { - "execution_mode": "off" + }, + "execution_count": 43, + "metadata": {}, + "output_type": "execute_result" } + ], + "source": [ + "from sklearn import config_context, datasets\n", + "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n", + "\n", + "iris = datasets.load_iris()\n", + "\n", + "X = iris.data\n", + "y = iris.target\n", + "\n", + "\n", + "def fit(X, y):\n", + " with config_context(array_api_dispatch=True):\n", + " lda = LinearDiscriminantAnalysis(n_components=2)\n", + " return lda.fit(X, y).transform(X)\n", + "\n", + "\n", + "fit(X, y)[:5]" + ] + }, + { + "cell_type": "markdown", + "id": "de801623-8f64-450e-b6bf-4e53e2bdcbe6", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "source": [ + "Could we execute this symbolically?\n", + "\n", + "```python\n", + "@egraph.class_\n", + "class NDArray(Expr):\n", + " @classmethod\n", + " def var(cls, name: StringLike) -> NDArray:\n", + " ...\n", + "\n", + " ...\n", + "X_arr = NDArray.var(\"X\")\n", + "y_arr = NDArray.var(\"y\")\n", + "fit(X_arr, y_arr)\n", + "```\n", + "\n", + "Started working on this yesterday...\n" + ] + }, + { + "cell_type": "markdown", + "id": "20078da0-a583-414a-853c-0a8a410ce5ff", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "source": [ + "Provide egglog with metadata at least about the types, to get through sklearn's sanity checks (which need to be executed eagerly):\n", + "\n", + "```python\n", + "egraph.register(\n", + " rewrite(X_arr.dtype).to(convert(X.dtype, DType)),\n", + " rewrite(y_arr.dtype).to(convert(y.dtype, DType)),\n", + " rewrite(isfinite(sum(X_arr)).bool()).to(TRUE),\n", + " rewrite(isfinite(sum(y_arr)).bool()).to(TRUE),\n", + " rewrite(X_arr.shape).to(convert(X.shape, TupleInt)),\n", + " rewrite(y_arr.shape).to(convert(y.shape, TupleInt)),\n", + " rewrite(X_arr.size).to(Int(X.size)),\n", + " rewrite(y_arr.size).to(Int(y.size)),\n", + " rewrite(unique_values(y_arr).shape).to(TupleInt(Int(3)))\n", + ")\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "85112e88-b0e7-4cb3-b3fd-7365fb95f16f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "source": [ + "Define all the required Array API functions:\n", + "\n", + "```python\n", + "@egraph.function\n", + "def reshape(x: NDArray, shape: TupleInt, copy: OptionalBool = OptionalBool.none) -> NDArray:\n", + " ...\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "4d36583e-69b0-4698-9792-99799d261782", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "source": [ + "```python\n", + "@egraph.register\n", + "def _reshape(x: NDArray, y: NDArray, shape: TupleInt, copy: OptionalBool, i: Int, s: String):\n", + " return [\n", + " # dtype of result is same as input\n", + " rewrite(\n", + " reshape(x, shape, copy).dtype\n", + " ).to(x.dtype),\n", + " # dimensions of output are the same as length of shape\n", + " rewrite(\n", + " reshape(x, shape, copy).shape.length()\n", + " ).to(shape.length()),\n", + " # Shape of single dimensions reshape is the # elements\n", + " rewrite(\n", + " reshape(x, TupleInt(Int(-1)), copy).shape\n", + " ).to(TupleInt(x.size)),\n", + " # Reshaping one dimension no-op\n", + " rule(\n", + " eq(y).to(reshape(x, TupleInt(Int(-1)), copy)),\n", + " eq(x.shape).to(TupleInt(i)),\n", + " ).then(\n", + " union(x).with_(y)\n", + " )\n", + " ]\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "bc1cf64c-f7bf-4ebb-ae55-1b74ea6d795e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" + }, + "tags": [] + }, + "source": [ + "Can see some examples of rewrites executing during sklearns checking:\n", + "\n", + "```python\n", + "asarray(reshape(asarray(NDArray.var(\"y\")), (TupleInt(Int(-1)) + TupleInt.EMPTY))).shape[Int(0)] == asarray(NDArray.var(\"X\")).shape[Int(0)]\n", + " -> NDArray.var(\"y\").size == NDArray.var(\"X\").shape[Int(0)]\n", + " -> TRUE\n", + "\n", + "asarray(asarray(reshape(asarray(NDArray.var(\"y\")), (TupleInt(Int(-1)) + TupleInt.EMPTY)))).ndim == Int(2)\n", + " -> FALSE\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "ddf19e72-5204-41f8-860e-cf45dfc0fc20", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "That's as far as I got!\n" + ] + }, + { + "cell_type": "markdown", + "id": "2b67e0b8-3c8d-45a5-a041-4293da7aed9e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## Conclusion\n", + "\n", + "- e-graphs are a data structure we can use to build term rewriting systems\n", + "- `egglog` is a language, and Python library, for building e-graphs\n", + "- Looking forward to seeing how it might be used in PyData ecosystem\n", + "\n", + "```bash\n", + "pip install egglog\n", + "```\n", + "\n", + "Welcome new contributations, experiments, and conversations...\n", + "\n", + "_Come say hello at [github.com/egraphs-good/egglog-python](https://github.com/egraphs-good/egglog-python) ad [egraphs.zulipchat.com](https://egraphs.zulipchat.com/)!_\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8a7fea36-c3f8-4fc2-970b-98ad2f439387", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "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.10.12" }, - "nbformat": 4, - "nbformat_minor": 5 + "mystnb": { + "execution_mode": "off" + } + }, + "nbformat": 4, + "nbformat_minor": 5 } diff --git a/docs/explanation/2023_11_09_portland_state.ipynb b/docs/explanation/2023_11_09_portland_state.ipynb index 7c4e9a47..84593c0f 100644 --- a/docs/explanation/2023_11_09_portland_state.ipynb +++ b/docs/explanation/2023_11_09_portland_state.ipynb @@ -2,6 +2,7 @@ "cells": [ { "cell_type": "markdown", + "id": "7fb27b941602401d91542211134fc71a", "metadata": { "notebookRunGroups": { "groupValue": "1" @@ -457,6 +458,7 @@ "outputs": [], "source": [ "from __future__ import annotations\n", + "\n", "from egglog import *\n", "\n", "egraph = EGraph()\n", @@ -465,16 +467,13 @@ "# 1. Describe domain with types & functions\n", "@egraph.class_\n", "class Num(Expr):\n", - " def __init__(self, i: i64Like) -> None:\n", - " ...\n", + " def __init__(self, i: i64Like) -> None: ...\n", "\n", - " def __add__(self, other: Num) -> Num:\n", - " ...\n", + " def __add__(self, other: Num) -> Num: ...\n", "\n", "\n", "@egraph.function(cost=20)\n", - "def fib(x: i64Like) -> Num:\n", - " ..." + "def fib(x: i64Like) -> Num: ..." ] }, { @@ -1406,6 +1405,7 @@ "outputs": [], "source": [ "import timeit\n", + "\n", "import pandas as pd\n", "import seaborn as sns\n", "\n", @@ -1413,9 +1413,9 @@ " \"original\": \"run_lda(X_np, y_np)\",\n", " \"numba\": \"numba_fn(X_np, y_np)\",\n", "}\n", - "df = pd.DataFrame.from_dict(\n", - " {name: timeit.repeat(stmt, globals=globals(), number=1, repeat=10) for name, stmt in stmts.items()}\n", - ")\n", + "df = pd.DataFrame.from_dict({\n", + " name: timeit.repeat(stmt, globals=globals(), number=1, repeat=10) for name, stmt in stmts.items()\n", + "})\n", "df_melt = pd.melt(df, var_name=\"function\", value_name=\"time\")" ] }, diff --git a/docs/explanation/2023_11_17_pytensor.ipynb b/docs/explanation/2023_11_17_pytensor.ipynb index fcae7f9c..776d0c0a 100644 --- a/docs/explanation/2023_11_17_pytensor.ipynb +++ b/docs/explanation/2023_11_17_pytensor.ipynb @@ -1,2552 +1,2530 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```{post} 2023-11-17\n", - "\n", - "```\n", - "\n", - "# [PyTensor](https://github.com/pymc-devs/pytensor) Chat\n", - "\n", - "Ricardo Vieira reached out asking to see if we could chat about egglog and to explore if it could be used inside\n", - "of PyTensor for rewriting.\n", - "\n", - "We set up a call and he aggreed to record it, so that we could share anything we talked about with others:\n" - ] - }, + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "```{post} 2023-11-17\n", + "\n", + "```\n", + "\n", + "# [PyTensor](https://github.com/pymc-devs/pytensor) Chat\n", + "\n", + "Ricardo Vieira reached out asking to see if we could chat about egglog and to explore if it could be used inside\n", + "of PyTensor for rewriting.\n", + "\n", + "We set up a call and he aggreed to record it, so that we could share anything we talked about with others:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [ + "hide-input" + ] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "tags": [ - "hide-input" - ] - }, - "outputs": [ - { - "data": { - "image/jpeg": "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", - "text/html": [ - "\n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/jpeg": "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", + "text/html": [ + "\n", + " \n", + " " ], - "source": [ - "from IPython.display import YouTubeVideo\n", - "\n", - "YouTubeVideo(\"8rb841pBhf0\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "It was great to get some feedback on the Python bindings and see where the rough patches are. So thank you Ricardo for\n", - "being game to explore this together!\n", - "\n", - "Some of the main takeaways for me where:\n", - "\n", - "- Having generic user defined sorts in egglog would be very useful, so that every library like PyTensor doesn't\n", - " have to reimplement collection types for every sort. If we had them, we could say implement a `egglog.std.Tuple`\n", - " class that would work like a tuple, and if you had a user defined `Int` class, you could do `Tuple[Int]`.\n", - "- It was interested to see how Ricardo started implementing the Op types at the end, as custom classes, and translating\n", - " the pure functions to them. It's a nice example of how you can write multiple interfaces, depending on the user,\n", - " and right rewrites in whichever you are more comfortable with, as long as you can convert to/from them.\n", - "\n", - "Some further things we could explore in the future are:\n", - "\n", - "- implementing loop nesting in egglog\n", - "- converting between the existing PyTensor types and egglog types, in a programatic way, so that we could play with rewrites\n", - " without having to rewrite their whole project.\n", - "\n", - "If anyone else who works on a Python library thinks they could benefit from egglog, or have other questions, feel free\n", - "to reach out!\n", - "\n", - "A cleaned up version of the notebook is below:\n", - "\n", - "---\n" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "ZmFq-i9By7V4" - }, - "outputs": [], - "source": [ - "%%capture\n", - "!pip install egglog\n", - "!pip install anywidget" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "itgwmxIGy929" - }, - "outputs": [], - "source": [ - "from __future__ import annotations\n", - "from typing import ClassVar, Tuple\n", - "\n", - "from functools import partial\n", - "from egglog import *" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "fBDfQ7Y5y_8d" - }, - "outputs": [], - "source": [ - "import numpy as np\n", - "import pytensor\n", - "import pytensor.tensor as pt" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "xWZfT2oq8a3U" - }, - "outputs": [], - "source": [ - "from traitlets.traitlets import Type\n", - "\n", - "egraph = EGraph()\n", - "\n", - "\n", - "@egraph.class_\n", - "class Int(Expr):\n", - " def __init__(self, value: i64Like) -> None:\n", - " ...\n", - "\n", - " @classmethod\n", - " def var(cls, name: StringLike) -> Int:\n", - " ...\n", - "\n", - "\n", - "converter(i64, Int, Int)\n", - "\n", - "\n", - "@egraph.class_\n", - "class IntTuple(Expr):\n", - " def __init__(self, first: Int) -> None:\n", - " ...\n", - "\n", - " @classmethod\n", - " def empty(cls) -> IntTuple:\n", - " ...\n", - "\n", - " def __add__(self, other: IntTuple) -> IntTuple:\n", - " ...\n", - "\n", - " def length(self) -> Int:\n", - " ...\n", - "\n", - " def __getitem__(self, i: Int) -> Int:\n", - " ...\n", - "\n", - "\n", - "converter(\n", - " tuple,\n", - " IntTuple,\n", - " lambda x: (\n", - " IntTuple(convert(x[0], Int)) + convert(x[1:], IntTuple)\n", - " if len(x) > 1\n", - " else (IntTuple(convert(x[0], Int)) if x else IntTuple.empty())\n", - " ),\n", - ")\n", - "converter(int, IntTuple, lambda i: IntTuple(Int(i64(i))))\n", - "converter(i64, IntTuple, lambda i: IntTuple(Int(i)))\n", - "converter(Int, IntTuple, lambda i: IntTuple(i))\n", - "\n", - "\n", - "@egraph.register\n", - "def int_tuple_rules(int_tuple: IntTuple, i: i64, j: i64):\n", - " # Handle tuple concatenation and access\n", - " yield rewrite(IntTuple(i)[0]).to(Int(i))\n", - " yield rewrite((IntTuple(i) + int_tuple)[0]).to(Int(i))\n", - " yield rewrite((IntTuple(i) + int_tuple)[j]).to(int_tuple[Int(j - 1)], j > 0)\n", - "\n", - "\n", - "Shape = IntTuple\n", - "\n", - "\n", - "@egraph.class_\n", - "class Tensor(Expr):\n", - " def __init__(self, name: StringLike, shape: Shape) -> None:\n", - " ...\n", - "\n", - " @property\n", - " def shape(self) -> Shape:\n", - " ...\n", - "\n", - " @property\n", - " def ndim(self) -> i64:\n", - " ...\n", - "\n", - "\n", - "@egraph.register\n", - "def inline_tensor_shape(x: Tensor, name: String, shape: Shape, i: Int):\n", - " yield rewrite(Tensor(name, shape).shape).to(shape)\n", - "\n", - "\n", - "@egraph.class_\n", - "class UnaryOp(Expr):\n", - " def __call__(self, x: Tensor) -> Tensor:\n", - " ...\n", - "\n", - "\n", - "@egraph.class_\n", - "class BinaryOp(Expr):\n", - " def __call__(self, x: Tensor, y: Tensor) -> Tensor:\n", - " ...\n", - "\n", - "\n", - "@egraph.function(cost=1)\n", - "def Squeeze(axis: IntTuple) -> UnaryOp:\n", - " ...\n", - "\n", - "\n", - "def split_merge_reorder_axis_op(op, x: Tensor, axis: IntTuple, i: i64, j: i64):\n", - " # Split into consecutive axis applications\n", - " yield (rewrite(op(axis=(i,) + axis)(x)).to(op(axis=(i,))(op(axis=axis)(x))))\n", - " # Swap consecutive axis applications\n", - " yield (\n", - " rewrite(op(axis=(i,))(op(axis=(j,))(x))).to(\n", - " op(axis=(j - 1,))(op(axis=(i,))(x)),\n", - " i < j,\n", - " )\n", - " )\n", - " yield (\n", - " rewrite(op(axis=(i,))(op(axis=(j,))(x))).to(\n", - " op(axis=(j,))(op(axis=(i + 1,))(x)),\n", - " i > j,\n", - " )\n", - " )\n", - " # Merge from consecutive axis applications\n", - " yield (\n", - " rewrite(op(axis=(i,))(op(axis=(j,))(x))).to(\n", - " op(axis=(i, j))(x),\n", - " i < j,\n", - " )\n", - " )\n", - " yield (\n", - " rewrite(op(axis=(i,))(op(axis=(j,) + axis)(x))).to(\n", - " op(axis=(i,) + (j + axis))(x),\n", - " i < j,\n", - " )\n", - " )\n", - "\n", - "\n", - "@egraph.register\n", - "def squeeze_rules(\n", - " x: Tensor,\n", - " axis: IntTuple,\n", - " i: i64,\n", - " j: i64,\n", - "):\n", - " yield from split_merge_reorder_axis_op(Squeeze, x, axis, i, j)\n", - "\n", - " # Squeeze.shape\n", - " yield (rewrite(Squeeze(axis=(i,))(x).shape[j]).to(x.shape[j + 1], i <= j))\n", - " yield (rewrite(Squeeze(axis=(i,))(x).shape[j]).to(x.shape[j], i > j))\n", - "\n", - "\n", - "@egraph.class_\n", - "class OpType(Expr):\n", - " ...\n", - "\n", - "\n", - "ScalarAdd = egraph.constant(\"ScalarAdd\", OpType)\n", - "ScalarMul = egraph.constant(\"ScalarMul\", OpType)\n", - "ScalarDiv = egraph.constant(\"ScalarDiv\", OpType)\n", - "\n", - "\n", - "@egraph.function(cost=10)\n", - "def Reduce(scalar_op: OpType, axis: IntTuple) -> UnaryOp:\n", - " ...\n", - "\n", - "\n", - "@egraph.function(cost=5)\n", - "def Elemwise(scalar_op: OpType) -> BinaryOp:\n", - " ...\n", - "\n", - "\n", - "Mul = Elemwise(ScalarMul)\n", - "Div = Elemwise(ScalarDiv)\n", - "Sum = partial(Reduce, ScalarAdd)\n", - "\n", - "\n", - "@egraph.register\n", - "def sum_rules(\n", - " x: Tensor,\n", - " y: Tensor,\n", - " z: Tensor,\n", - " i: i64,\n", - " j: i64,\n", - " axis: IntTuple,\n", - " axis2: IntTuple,\n", - " op: OpType,\n", - "):\n", - " any_reduce_op = partial(Reduce, op)\n", - " yield from split_merge_reorder_axis_op(any_reduce_op, x, axis, i, j)\n", - "\n", - " # Introduce shape[i] needed for removing useless reductions\n", - " yield (rule(eq(y).to(any_reduce_op(axis=(i,))(x))).then(x.shape[i]))\n", - "\n", - " # Remove useless reductions\n", - " yield (rewrite(any_reduce_op(axis=(i,))(x)).to(Squeeze(axis=(i,))(x), eq(x.shape[i]).to(Int(1))))\n", - "\n", - " # Introduce shape[i] needed for factoring out multiplication/division out of sum\n", - " yield (rule(eq(z).to(Sum(axis=(i,))(Elemwise(op)(x, y)))).then(y.shape[i]))\n", - "\n", - " # Factor multiplication/division out of sum\n", - " for elemwise_op in (Mul, Div):\n", - " yield (\n", - " rewrite(Sum(axis=(i,))(elemwise_op(x, y))).to(\n", - " elemwise_op(\n", - " Sum(axis=(i,))(x),\n", - " Squeeze(axis=(i,))(y),\n", - " ),\n", - " eq(y.shape[i]).to(Int(1)),\n", - " )\n", - " )\n", - "\n", - "\n", - "x = Tensor(\"x\", (Int.var(\"x_dim_0\"), 5, 7))\n", - "y = Tensor(\"y\", (1, 5, 1))\n", - "expr = Sum(axis=(0, 2))(Div(x, y))\n", - "# expr = Sum(axis=(0, 2))(y)\n", - "\n", - "egraph.register(expr)\n", - "# egraph" + "text/plain": [ + "" ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from IPython.display import YouTubeVideo\n", + "\n", + "YouTubeVideo(\"8rb841pBhf0\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "It was great to get some feedback on the Python bindings and see where the rough patches are. So thank you Ricardo for\n", + "being game to explore this together!\n", + "\n", + "Some of the main takeaways for me where:\n", + "\n", + "- Having generic user defined sorts in egglog would be very useful, so that every library like PyTensor doesn't\n", + " have to reimplement collection types for every sort. If we had them, we could say implement a `egglog.std.Tuple`\n", + " class that would work like a tuple, and if you had a user defined `Int` class, you could do `Tuple[Int]`.\n", + "- It was interested to see how Ricardo started implementing the Op types at the end, as custom classes, and translating\n", + " the pure functions to them. It's a nice example of how you can write multiple interfaces, depending on the user,\n", + " and right rewrites in whichever you are more comfortable with, as long as you can convert to/from them.\n", + "\n", + "Some further things we could explore in the future are:\n", + "\n", + "- implementing loop nesting in egglog\n", + "- converting between the existing PyTensor types and egglog types, in a programatic way, so that we could play with rewrites\n", + " without having to rewrite their whole project.\n", + "\n", + "If anyone else who works on a Python library thinks they could benefit from egglog, or have other questions, feel free\n", + "to reach out!\n", + "\n", + "A cleaned up version of the notebook is below:\n", + "\n", + "---\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "ZmFq-i9By7V4" + }, + "outputs": [], + "source": [ + "%%capture\n", + "!pip install egglog\n", + "!pip install anywidget" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "itgwmxIGy929" + }, + "outputs": [], + "source": [ + "from __future__ import annotations\n", + "\n", + "from functools import partial\n", + "\n", + "from egglog import *" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "fBDfQ7Y5y_8d" + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "xWZfT2oq8a3U" + }, + "outputs": [], + "source": [ + "egraph = EGraph()\n", + "\n", + "\n", + "@egraph.class_\n", + "class Int(Expr):\n", + " def __init__(self, value: i64Like) -> None: ...\n", + "\n", + " @classmethod\n", + " def var(cls, name: StringLike) -> Int: ...\n", + "\n", + "\n", + "converter(i64, Int, Int)\n", + "\n", + "\n", + "@egraph.class_\n", + "class IntTuple(Expr):\n", + " def __init__(self, first: Int) -> None: ...\n", + "\n", + " @classmethod\n", + " def empty(cls) -> IntTuple: ...\n", + "\n", + " def __add__(self, other: IntTuple) -> IntTuple: ...\n", + "\n", + " def length(self) -> Int: ...\n", + "\n", + " def __getitem__(self, i: Int) -> Int: ...\n", + "\n", + "\n", + "converter(\n", + " tuple,\n", + " IntTuple,\n", + " lambda x: (\n", + " IntTuple(convert(x[0], Int)) + convert(x[1:], IntTuple)\n", + " if len(x) > 1\n", + " else (IntTuple(convert(x[0], Int)) if x else IntTuple.empty())\n", + " ),\n", + ")\n", + "converter(int, IntTuple, lambda i: IntTuple(Int(i64(i))))\n", + "converter(i64, IntTuple, lambda i: IntTuple(Int(i)))\n", + "converter(Int, IntTuple, lambda i: IntTuple(i))\n", + "\n", + "\n", + "@egraph.register\n", + "def int_tuple_rules(int_tuple: IntTuple, i: i64, j: i64):\n", + " # Handle tuple concatenation and access\n", + " yield rewrite(IntTuple(i)[0]).to(Int(i))\n", + " yield rewrite((IntTuple(i) + int_tuple)[0]).to(Int(i))\n", + " yield rewrite((IntTuple(i) + int_tuple)[j]).to(int_tuple[Int(j - 1)], j > 0)\n", + "\n", + "\n", + "Shape = IntTuple\n", + "\n", + "\n", + "@egraph.class_\n", + "class Tensor(Expr):\n", + " def __init__(self, name: StringLike, shape: Shape) -> None: ...\n", + "\n", + " @property\n", + " def shape(self) -> Shape: ...\n", + "\n", + " @property\n", + " def ndim(self) -> i64: ...\n", + "\n", + "\n", + "@egraph.register\n", + "def inline_tensor_shape(x: Tensor, name: String, shape: Shape, i: Int):\n", + " yield rewrite(Tensor(name, shape).shape).to(shape)\n", + "\n", + "\n", + "@egraph.class_\n", + "class UnaryOp(Expr):\n", + " def __call__(self, x: Tensor) -> Tensor: ...\n", + "\n", + "\n", + "@egraph.class_\n", + "class BinaryOp(Expr):\n", + " def __call__(self, x: Tensor, y: Tensor) -> Tensor: ...\n", + "\n", + "\n", + "@egraph.function(cost=1)\n", + "def Squeeze(axis: IntTuple) -> UnaryOp: ...\n", + "\n", + "\n", + "def split_merge_reorder_axis_op(op, x: Tensor, axis: IntTuple, i: i64, j: i64):\n", + " # Split into consecutive axis applications\n", + " yield (rewrite(op(axis=(i, *axis))(x)).to(op(axis=(i,))(op(axis=axis)(x))))\n", + " # Swap consecutive axis applications\n", + " yield (\n", + " rewrite(op(axis=(i,))(op(axis=(j,))(x))).to(\n", + " op(axis=(j - 1,))(op(axis=(i,))(x)),\n", + " i < j,\n", + " )\n", + " )\n", + " yield (\n", + " rewrite(op(axis=(i,))(op(axis=(j,))(x))).to(\n", + " op(axis=(j,))(op(axis=(i + 1,))(x)),\n", + " i > j,\n", + " )\n", + " )\n", + " # Merge from consecutive axis applications\n", + " yield (\n", + " rewrite(op(axis=(i,))(op(axis=(j,))(x))).to(\n", + " op(axis=(i, j))(x),\n", + " i < j,\n", + " )\n", + " )\n", + " yield (\n", + " rewrite(op(axis=(i,))(op(axis=(j, *axis))(x))).to(\n", + " op(axis=(i,) + (j + axis))(x),\n", + " i < j,\n", + " )\n", + " )\n", + "\n", + "\n", + "@egraph.register\n", + "def squeeze_rules(\n", + " x: Tensor,\n", + " axis: IntTuple,\n", + " i: i64,\n", + " j: i64,\n", + "):\n", + " yield from split_merge_reorder_axis_op(Squeeze, x, axis, i, j)\n", + "\n", + " # Squeeze.shape\n", + " yield (rewrite(Squeeze(axis=(i,))(x).shape[j]).to(x.shape[j + 1], i <= j))\n", + " yield (rewrite(Squeeze(axis=(i,))(x).shape[j]).to(x.shape[j], i > j))\n", + "\n", + "\n", + "@egraph.class_\n", + "class OpType(Expr): ...\n", + "\n", + "\n", + "ScalarAdd = egraph.constant(\"ScalarAdd\", OpType)\n", + "ScalarMul = egraph.constant(\"ScalarMul\", OpType)\n", + "ScalarDiv = egraph.constant(\"ScalarDiv\", OpType)\n", + "\n", + "\n", + "@egraph.function(cost=10)\n", + "def Reduce(scalar_op: OpType, axis: IntTuple) -> UnaryOp: ...\n", + "\n", + "\n", + "@egraph.function(cost=5)\n", + "def Elemwise(scalar_op: OpType) -> BinaryOp: ...\n", + "\n", + "\n", + "Mul = Elemwise(ScalarMul)\n", + "Div = Elemwise(ScalarDiv)\n", + "Sum = partial(Reduce, ScalarAdd)\n", + "\n", + "\n", + "@egraph.register\n", + "def sum_rules(\n", + " x: Tensor,\n", + " y: Tensor,\n", + " z: Tensor,\n", + " i: i64,\n", + " j: i64,\n", + " axis: IntTuple,\n", + " axis2: IntTuple,\n", + " op: OpType,\n", + "):\n", + " any_reduce_op = partial(Reduce, op)\n", + " yield from split_merge_reorder_axis_op(any_reduce_op, x, axis, i, j)\n", + "\n", + " # Introduce shape[i] needed for removing useless reductions\n", + " yield (rule(eq(y).to(any_reduce_op(axis=(i,))(x))).then(x.shape[i]))\n", + "\n", + " # Remove useless reductions\n", + " yield (rewrite(any_reduce_op(axis=(i,))(x)).to(Squeeze(axis=(i,))(x), eq(x.shape[i]).to(Int(1))))\n", + "\n", + " # Introduce shape[i] needed for factoring out multiplication/division out of sum\n", + " yield (rule(eq(z).to(Sum(axis=(i,))(Elemwise(op)(x, y)))).then(y.shape[i]))\n", + "\n", + " # Factor multiplication/division out of sum\n", + " for elemwise_op in (Mul, Div):\n", + " yield (\n", + " rewrite(Sum(axis=(i,))(elemwise_op(x, y))).to(\n", + " elemwise_op(\n", + " Sum(axis=(i,))(x),\n", + " Squeeze(axis=(i,))(y),\n", + " ),\n", + " eq(y.shape[i]).to(Int(1)),\n", + " )\n", + " )\n", + "\n", + "\n", + "x = Tensor(\"x\", (Int.var(\"x_dim_0\"), 5, 7))\n", + "y = Tensor(\"y\", (1, 5, 1))\n", + "expr = Sum(axis=(0, 2))(Div(x, y))\n", + "# expr = Sum(axis=(0, 2))(y)\n", + "\n", + "egraph.register(expr)\n", + "# egraph" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 1000 }, + "id": "rAcuuaK55_ks", + "outputId": "c3fe65ef-038b-4b4f-cb7f-a3e9fddc6301" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "id": "rAcuuaK55_ks", - "outputId": "c3fe65ef-038b-4b4f-cb7f-a3e9fddc6301" - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "%3\n", - "\n", - "\n", - "outer_cluster_8\n", - "\n", - "\n", - "cluster_8\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_35\n", - "\n", - "\n", - "cluster_35\n", - "\n", - "\n", - "\n", - "outer_cluster_40\n", - "\n", - "\n", - "cluster_40\n", - "\n", - "\n", - "\n", - "outer_cluster_51\n", - "\n", - "\n", - "cluster_51\n", - "\n", - "\n", - "\n", - "outer_cluster_13\n", - "\n", - "\n", - "cluster_13\n", - "\n", - "\n", - "\n", - "outer_cluster_71\n", - "\n", - "\n", - "cluster_71\n", - "\n", - "\n", - "\n", - "outer_cluster_62\n", - "\n", - "\n", - "cluster_62\n", - "\n", - "\n", - "\n", - "outer_cluster_9\n", - "\n", - "\n", - "cluster_9\n", - "\n", - "\n", - "\n", - "outer_cluster_37\n", - "\n", - "\n", - "cluster_37\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_66\n", - "\n", - "\n", - "cluster_66\n", - "\n", - "\n", - "\n", - "outer_cluster_11\n", - "\n", - "\n", - "cluster_11\n", - "\n", - "\n", - "\n", - "outer_cluster_61\n", - "\n", - "\n", - "cluster_61\n", - "\n", - "\n", - "\n", - "outer_cluster_41\n", - "\n", - "\n", - "cluster_41\n", - "\n", - "\n", - "\n", - "outer_cluster_10\n", - "\n", - "\n", - "cluster_10\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_60\n", - "\n", - "\n", - "cluster_60\n", - "\n", - "\n", - "\n", - "outer_cluster_65\n", - "\n", - "\n", - "cluster_65\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "outer_cluster_19\n", - "\n", - "\n", - "cluster_19\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_20\n", - "\n", - "\n", - "cluster_20\n", - "\n", - "\n", - "\n", - "outer_cluster_12\n", - "\n", - "\n", - "cluster_12\n", - "\n", - "\n", - "\n", - "outer_cluster_29\n", - "\n", - "\n", - "cluster_29\n", - "\n", - "\n", - "\n", - "outer_cluster_36\n", - "\n", - "\n", - "cluster_36\n", - "\n", - "\n", - "\n", - "outer_cluster_48\n", - "\n", - "\n", - "cluster_48\n", - "\n", - "\n", - "\n", - "outer_cluster_15\n", - "\n", - "\n", - "cluster_15\n", - "\n", - "\n", - "\n", - "outer_cluster_50\n", - "\n", - "\n", - "cluster_50\n", - "\n", - "\n", - "\n", - "outer_cluster_70\n", - "\n", - "\n", - "cluster_70\n", - "\n", - "\n", - "\n", - "outer_cluster_34\n", - "\n", - "\n", - "cluster_34\n", - "\n", - "\n", - "\n", - "outer_cluster_39\n", - "\n", - "\n", - "cluster_39\n", - "\n", - "\n", - "\n", - "outer_cluster_14\n", - "\n", - "\n", - "cluster_14\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "outer_cluster_String-1618856268753343266\n", - "\n", - "\n", - "cluster_String-1618856268753343266\n", - "\n", - "\n", - "\n", - "outer_cluster_String-313937328870544552\n", - "\n", - "\n", - "cluster_String-313937328870544552\n", - "\n", - "\n", - "\n", - "outer_cluster_String-6766843149853318713\n", - "\n", - "\n", - "cluster_String-6766843149853318713\n", - "\n", - "\n", - "\n", - "outer_cluster_22\n", - "\n", - "\n", - "cluster_22\n", - "\n", - "\n", - "\n", - "outer_cluster_45\n", - "\n", - "\n", - "cluster_45\n", - "\n", - "\n", - "\n", - "outer_cluster_23\n", - "\n", - "\n", - "cluster_23\n", - "\n", - "\n", - "\n", - "outer_cluster_58\n", - "\n", - "\n", - "cluster_58\n", - "\n", - "\n", - "\n", - "outer_cluster_52\n", - "\n", - "\n", - "cluster_52\n", - "\n", - "\n", - "\n", - "outer_cluster_54\n", - "\n", - "\n", - "cluster_54\n", - "\n", - "\n", - "\n", - "outer_cluster_56\n", - "\n", - "\n", - "cluster_56\n", - "\n", - "\n", - "\n", - "outer_cluster_24\n", - "\n", - "\n", - "cluster_24\n", - "\n", - "\n", - "\n", - "outer_cluster_32\n", - "\n", - "\n", - "cluster_32\n", - "\n", - "\n", - "\n", - "outer_cluster_43\n", - "\n", - "\n", - "cluster_43\n", - "\n", - "\n", - "\n", - "outer_cluster_27\n", - "\n", - "\n", - "cluster_27\n", - "\n", - "\n", - "\n", - "outer_cluster_17\n", - "\n", - "\n", - "cluster_17\n", - "\n", - "\n", - "\n", - "outer_cluster_67\n", - "\n", - "\n", - "cluster_67\n", - "\n", - "\n", - "\n", - "outer_cluster_26\n", - "\n", - "\n", - "cluster_26\n", - "\n", - "\n", - "\n", - "outer_cluster_25\n", - "\n", - "\n", - "cluster_25\n", - "\n", - "\n", - "\n", - "outer_cluster_53\n", - "\n", - "\n", - "cluster_53\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_44\n", - "\n", - "\n", - "cluster_44\n", - "\n", - "\n", - "\n", - "outer_cluster_57\n", - "\n", - "\n", - "cluster_57\n", - "\n", - "\n", - "\n", - "outer_cluster_31\n", - "\n", - "\n", - "cluster_31\n", - "\n", - "\n", - "\n", - "outer_cluster_i64-4208978898528913939\n", - "\n", - "\n", - "cluster_i64-4208978898528913939\n", - "\n", - "\n", - "\n", - "outer_cluster_i64-5871781006564002453\n", - "\n", - "\n", - "cluster_i64-5871781006564002453\n", - "\n", - "\n", - "\n", - "outer_cluster_i64-10912160959110460649\n", - "\n", - "\n", - "cluster_i64-10912160959110460649\n", - "\n", - "\n", - "\n", - "outer_cluster_i64-11743562013128004906\n", - "\n", - "\n", - "cluster_i64-11743562013128004906\n", - "\n", - "\n", - "\n", - "outer_cluster_i64-0\n", - "\n", - "\n", - "cluster_i64-0\n", - "\n", - "\n", - "\n", - "\n", - "Elemwise-4208978898528913939:s->ScalarDiv-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-11743562013128004906:s->i64-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-2427221081489190903:s->Tensor_shape-10964134587551653303\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-2427221081489190903:s->Int___init__-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-10964134587551653303:s->UnaryOp___call__-8391183972302725451\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-0:s->i64-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-14535344522394967184:s->Tensor_shape-3429551472952562336\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-14535344522394967184:s->IntTuple___getitem__-8609920828969388276\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-3429551472952562336:s->UnaryOp___call__-10760501220358611293\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-8609920828969388276:s->Int___init__-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-8609920828969388276:s->IntTuple___add__-3515898189561353625\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-6451836211519040652:s->Int___init__-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-6451836211519040652:s->IntTuple___add__-16058157226959687954\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-16058157226959687954:s->IntTuple___init__-15952540911656918845\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-16058157226959687954:s->IntTuple___add__-14593153318476900644\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-4208978898528913939:s->i64-4208978898528913939\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-6611095213683386216:s->Int___init__-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-6611095213683386216:s->Tensor_shape-10184707161975301700\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-10184707161975301700:s->UnaryOp___call__-10053986080337813965\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-18195398224647045558:s->Int___init__-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-18195398224647045558:s->Tensor_shape-7586556743040283621\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-7586556743040283621:s->Tensor___init__-1575189424824699418\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_var-1618856268753343266:s->String-1618856268753343266\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-7613425605146757649:s->Int___init__-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-7613425605146757649:s->Tensor_shape-5923754635005195107\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-5923754635005195107:s->BinaryOp___call__-4194065315749295272\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-14456597069198672103:s->Tensor_shape-12678910324027934471\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-14456597069198672103:s->IntTuple___getitem__-10395939792580839918\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-12678910324027934471:s->UnaryOp___call__-9097699112323522779\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-10395939792580839918:s->IntTuple___add__-5343794467401528509\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-10395939792580839918:s->IntTuple___getitem__-1906738768387841566\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-10912160959110460649:s->i64-10912160959110460649\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-5871781006564002453:s->i64-5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-14040062012979708074:s->Int___init__-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-14040062012979708074:s->Tensor_shape-3481525101393754990\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-3481525101393754990:s->UnaryOp___call__-3344968852115526449\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-5343794467401528509:s->IntTuple___init__-7690503999922668929\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-5343794467401528509:s->IntTuple___init__-9249358851075372135\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-1906738768387841566:s->Int___init__-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-1906738768387841566:s->Tensor_shape-51973628441192654\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-10514990538936846041:s->IntTuple___getitem__-14040062012979708074\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-10514990538936846041:s->Tensor_shape-5975728263446387761\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-5975728263446387761:s->UnaryOp___call__-4195639504827048526\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-3515898189561353625:s->IntTuple___add__-5343794467401528509\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-3515898189561353625:s->IntTuple___init__-7690503999922668929\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-9335705567684163424:s->Int___init__-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-9335705567684163424:s->IntTuple___init__-7690503999922668929\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-7690503999922668929:s->IntTuple___getitem__-10395939792580839918\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-51973628441192654:s->Tensor___init__-14358371401161707118\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-910243544565210939:s->Int___init__-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-910243544565210939:s->Tensor_shape-5923754635005195107\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-15952540911656918845:s->Int_var-1618856268753343266\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-5871781006564002453:s->Int___init__-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-3344968852115526449:s->Tensor___init__-14358371401161707118\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-3344968852115526449:s->Squeeze-5040379952546458196\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-9097699112323522779:s->Tensor___init__-1575189424824699418\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-9097699112323522779:s->Reduce-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-15318938057191675792:s->IntTuple___init__-5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-15318938057191675792:s->IntTuple___init__-17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-17615343019692007359:s->Int___init__-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-9249358851075372135:s->Int___init__-10912160959110460649\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor___init__-14358371401161707118:s->Tensor_shape-51973628441192654\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor___init__-14358371401161707118:s->String-6766843149853318713\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-4194065315749295272:s->Elemwise-4208978898528913939\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-4194065315749295272:s->Tensor___init__-14358371401161707118\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-4194065315749295272:s->Tensor___init__-1575189424824699418\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-4195639504827048526:s->Tensor___init__-14358371401161707118\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-4195639504827048526:s->Squeeze-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-14593153318476900644:s->IntTuple___init__-9249358851075372135\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-14593153318476900644:s->IntTuple___init__-2546176790493825425\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-2546176790493825425:s->Int___init__-4208978898528913939\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor___init__-1575189424824699418:s->Tensor_shape-7586556743040283621\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor___init__-1575189424824699418:s->String-313937328870544552\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-10053986080337813965:s->Tensor___init__-1575189424824699418\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-10053986080337813965:s->Reduce-5040379952546458196\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-8391183972302725451:s->BinaryOp___call__-4194065315749295272\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-8391183972302725451:s->Reduce-5040379952546458196\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-10760501220358611293:s->BinaryOp___call__-4194065315749295272\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-10760501220358611293:s->Reduce-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Squeeze-11743562013128004906:s->IntTuple___init__-5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-3636617994337743549:s->UnaryOp___call__-4195639504827048526\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-3636617994337743549:s->Squeeze-883374682458736911\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Squeeze-883374682458736911:s->IntTuple___init__-7690503999922668929\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-7625190977779610862:s->UnaryOp___call__-3344968852115526449\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-7625190977779610862:s->Squeeze-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-2183379458487809452:s->Tensor___init__-14358371401161707118\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-2183379458487809452:s->Squeeze-10912160959110460649\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Squeeze-10912160959110460649:s->IntTuple___add__-15318938057191675792\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-5040379952546458196:s->IntTuple___init__-17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-5040379952546458196:s->ScalarAdd-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Squeeze-5040379952546458196:s->IntTuple___init__-17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-15458927460662043536:s->UnaryOp___call__-9097699112323522779\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-15458927460662043536:s->Reduce-883374682458736911\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-883374682458736911:s->IntTuple___init__-7690503999922668929\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-883374682458736911:s->ScalarAdd-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-13202730753970051410:s->UnaryOp___call__-10053986080337813965\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-13202730753970051410:s->Reduce-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-11743562013128004906:s->IntTuple___init__-5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-11743562013128004906:s->ScalarAdd-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-593394598656903612:s->Tensor___init__-1575189424824699418\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-593394598656903612:s->Reduce-10912160959110460649\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-10912160959110460649:s->IntTuple___add__-15318938057191675792\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-10912160959110460649:s->ScalarAdd-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-7183646024568558754:s->Elemwise-4208978898528913939\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-7183646024568558754:s->UnaryOp___call__-7625190977779610862\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-7183646024568558754:s->UnaryOp___call__-13202730753970051410\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-7296576659238450322:s->BinaryOp___call__-4194065315749295272\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-7296576659238450322:s->Reduce-10912160959110460649\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-5720121267812153097:s->Reduce-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-5720121267812153097:s->BinaryOp___call__-17648236956133224341\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-17648236956133224341:s->Elemwise-4208978898528913939\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-17648236956133224341:s->UnaryOp___call__-3344968852115526449\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-17648236956133224341:s->UnaryOp___call__-10053986080337813965\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-6261542238027864055:s->Reduce-883374682458736911\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-6261542238027864055:s->BinaryOp___call__-4681938636454801376\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-4681938636454801376:s->Elemwise-4208978898528913939\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-4681938636454801376:s->UnaryOp___call__-9097699112323522779\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-4681938636454801376:s->UnaryOp___call__-4195639504827048526\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Elemwise-4208978898528913939\n", - "\n", - "\n", - "Elemwise\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ScalarDiv-0\n", - "\n", - "\n", - "ScalarDiv\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-11743562013128004906\n", - "\n", - "\n", - "Int___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "i64-11743562013128004906\n", - "\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-2427221081489190903\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-10964134587551653303\n", - "\n", - "\n", - "Tensor_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-0\n", - "\n", - "\n", - "Int___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-14535344522394967184\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-3429551472952562336\n", - "\n", - "\n", - "Tensor_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-8609920828969388276\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-6451836211519040652\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-16058157226959687954\n", - "\n", - "\n", - "IntTuple___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-4208978898528913939\n", - "\n", - "\n", - "Int___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "i64-4208978898528913939\n", - "\n", - "\n", - "7\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-6611095213683386216\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-10184707161975301700\n", - "\n", - "\n", - "Tensor_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-18195398224647045558\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-7586556743040283621\n", - "\n", - "\n", - "Tensor_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_var-1618856268753343266\n", - "\n", - "\n", - "Int_var\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "String-1618856268753343266\n", - "\n", - "\n", - ""x_dim_0"\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-7613425605146757649\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-5923754635005195107\n", - "\n", - "\n", - "Tensor_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "i64-0\n", - "\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-14456597069198672103\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-12678910324027934471\n", - "\n", - "\n", - "Tensor_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-10395939792580839918\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-10912160959110460649\n", - "\n", - "\n", - "Int___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "i64-10912160959110460649\n", - "\n", - "\n", - "5\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-5871781006564002453\n", - "\n", - "\n", - "Int___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "i64-5871781006564002453\n", - "\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-14040062012979708074\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-3481525101393754990\n", - "\n", - "\n", - "Tensor_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-5343794467401528509\n", - "\n", - "\n", - "IntTuple___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-1906738768387841566\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-10514990538936846041\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-5975728263446387761\n", - "\n", - "\n", - "Tensor_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-3515898189561353625\n", - "\n", - "\n", - "IntTuple___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-9335705567684163424\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-7690503999922668929\n", - "\n", - "\n", - "IntTuple___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor_shape-51973628441192654\n", - "\n", - "\n", - "Tensor_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___getitem__-910243544565210939\n", - "\n", - "\n", - "IntTuple___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-15952540911656918845\n", - "\n", - "\n", - "IntTuple___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-5871781006564002453\n", - "\n", - "\n", - "IntTuple___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-3344968852115526449\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-9097699112323522779\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-15318938057191675792\n", - "\n", - "\n", - "IntTuple___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-17615343019692007359\n", - "\n", - "\n", - "IntTuple___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-9249358851075372135\n", - "\n", - "\n", - "IntTuple___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor___init__-14358371401161707118\n", - "\n", - "\n", - "Tensor___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-4194065315749295272\n", - "\n", - "\n", - "BinaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-4195639504827048526\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___add__-14593153318476900644\n", - "\n", - "\n", - "IntTuple___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IntTuple___init__-2546176790493825425\n", - "\n", - "\n", - "IntTuple___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Tensor___init__-1575189424824699418\n", - "\n", - "\n", - "Tensor___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-10053986080337813965\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-8391183972302725451\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-10760501220358611293\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ScalarAdd-0\n", - "\n", - "\n", - "ScalarAdd\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "String-313937328870544552\n", - "\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "String-6766843149853318713\n", - "\n", - "\n", - ""y"\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Squeeze-11743562013128004906\n", - "\n", - "\n", - "Squeeze\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-3636617994337743549\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Squeeze-883374682458736911\n", - "\n", - "\n", - "Squeeze\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-7625190977779610862\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-2183379458487809452\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Squeeze-10912160959110460649\n", - "\n", - "\n", - "Squeeze\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-5040379952546458196\n", - "\n", - "\n", - "Reduce\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Squeeze-5040379952546458196\n", - "\n", - "\n", - "Squeeze\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-15458927460662043536\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-883374682458736911\n", - "\n", - "\n", - "Reduce\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-13202730753970051410\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-11743562013128004906\n", - "\n", - "\n", - "Reduce\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-593394598656903612\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Reduce-10912160959110460649\n", - "\n", - "\n", - "Reduce\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-7183646024568558754\n", - "\n", - "\n", - "BinaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-7296576659238450322\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-5720121267812153097\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-17648236956133224341\n", - "\n", - "\n", - "BinaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "UnaryOp___call__-6261542238027864055\n", - "\n", - "\n", - "UnaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "BinaryOp___call__-4681938636454801376\n", - "\n", - "\n", - "BinaryOp___call__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "%3\n", + "\n", + "\n", + "outer_cluster_8\n", + "\n", + "\n", + "cluster_8\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_35\n", + "\n", + "\n", + "cluster_35\n", + "\n", + "\n", + "\n", + "outer_cluster_40\n", + "\n", + "\n", + "cluster_40\n", + "\n", + "\n", + "\n", + "outer_cluster_51\n", + "\n", + "\n", + "cluster_51\n", + "\n", + "\n", + "\n", + "outer_cluster_13\n", + "\n", + "\n", + "cluster_13\n", + "\n", + "\n", + "\n", + "outer_cluster_71\n", + "\n", + "\n", + "cluster_71\n", + "\n", + "\n", + "\n", + "outer_cluster_62\n", + "\n", + "\n", + "cluster_62\n", + "\n", + "\n", + "\n", + "outer_cluster_9\n", + "\n", + "\n", + "cluster_9\n", + "\n", + "\n", + "\n", + "outer_cluster_37\n", + "\n", + "\n", + "cluster_37\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_66\n", + "\n", + "\n", + "cluster_66\n", + "\n", + "\n", + "\n", + "outer_cluster_11\n", + "\n", + "\n", + "cluster_11\n", + "\n", + "\n", + "\n", + "outer_cluster_61\n", + "\n", + "\n", + "cluster_61\n", + "\n", + "\n", + "\n", + "outer_cluster_41\n", + "\n", + "\n", + "cluster_41\n", + "\n", + "\n", + "\n", + "outer_cluster_10\n", + "\n", + "\n", + "cluster_10\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_60\n", + "\n", + "\n", + "cluster_60\n", + "\n", + "\n", + "\n", + "outer_cluster_65\n", + "\n", + "\n", + "cluster_65\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "outer_cluster_19\n", + "\n", + "\n", + "cluster_19\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_20\n", + "\n", + "\n", + "cluster_20\n", + "\n", + "\n", + "\n", + "outer_cluster_12\n", + "\n", + "\n", + "cluster_12\n", + "\n", + "\n", + "\n", + "outer_cluster_29\n", + "\n", + "\n", + "cluster_29\n", + "\n", + "\n", + "\n", + "outer_cluster_36\n", + "\n", + "\n", + "cluster_36\n", + "\n", + "\n", + "\n", + "outer_cluster_48\n", + "\n", + "\n", + "cluster_48\n", + "\n", + "\n", + "\n", + "outer_cluster_15\n", + "\n", + "\n", + "cluster_15\n", + "\n", + "\n", + "\n", + "outer_cluster_50\n", + "\n", + "\n", + "cluster_50\n", + "\n", + "\n", + "\n", + "outer_cluster_70\n", + "\n", + "\n", + "cluster_70\n", + "\n", + "\n", + "\n", + "outer_cluster_34\n", + "\n", + "\n", + "cluster_34\n", + "\n", + "\n", + "\n", + "outer_cluster_39\n", + "\n", + "\n", + "cluster_39\n", + "\n", + "\n", + "\n", + "outer_cluster_14\n", + "\n", + "\n", + "cluster_14\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "outer_cluster_String-1618856268753343266\n", + "\n", + "\n", + "cluster_String-1618856268753343266\n", + "\n", + "\n", + "\n", + "outer_cluster_String-313937328870544552\n", + "\n", + "\n", + "cluster_String-313937328870544552\n", + "\n", + "\n", + "\n", + "outer_cluster_String-6766843149853318713\n", + "\n", + "\n", + "cluster_String-6766843149853318713\n", + "\n", + "\n", + "\n", + "outer_cluster_22\n", + "\n", + "\n", + "cluster_22\n", + "\n", + "\n", + "\n", + "outer_cluster_45\n", + "\n", + "\n", + "cluster_45\n", + "\n", + "\n", + "\n", + "outer_cluster_23\n", + "\n", + "\n", + "cluster_23\n", + "\n", + "\n", + "\n", + "outer_cluster_58\n", + "\n", + "\n", + "cluster_58\n", + "\n", + "\n", + "\n", + "outer_cluster_52\n", + "\n", + "\n", + "cluster_52\n", + "\n", + "\n", + "\n", + "outer_cluster_54\n", + "\n", + "\n", + "cluster_54\n", + "\n", + "\n", + "\n", + "outer_cluster_56\n", + "\n", + "\n", + "cluster_56\n", + "\n", + "\n", + "\n", + "outer_cluster_24\n", + "\n", + "\n", + "cluster_24\n", + "\n", + "\n", + "\n", + "outer_cluster_32\n", + "\n", + "\n", + "cluster_32\n", + "\n", + "\n", + "\n", + "outer_cluster_43\n", + "\n", + "\n", + "cluster_43\n", + "\n", + "\n", + "\n", + "outer_cluster_27\n", + "\n", + "\n", + "cluster_27\n", + "\n", + "\n", + "\n", + "outer_cluster_17\n", + "\n", + "\n", + "cluster_17\n", + "\n", + "\n", + "\n", + "outer_cluster_67\n", + "\n", + "\n", + "cluster_67\n", + "\n", + "\n", + "\n", + "outer_cluster_26\n", + "\n", + "\n", + "cluster_26\n", + "\n", + "\n", + "\n", + "outer_cluster_25\n", + "\n", + "\n", + "cluster_25\n", + "\n", + "\n", + "\n", + "outer_cluster_53\n", + "\n", + "\n", + "cluster_53\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_44\n", + "\n", + "\n", + "cluster_44\n", + "\n", + "\n", + "\n", + "outer_cluster_57\n", + "\n", + "\n", + "cluster_57\n", + "\n", + "\n", + "\n", + "outer_cluster_31\n", + "\n", + "\n", + "cluster_31\n", + "\n", + "\n", + "\n", + "outer_cluster_i64-4208978898528913939\n", + "\n", + "\n", + "cluster_i64-4208978898528913939\n", + "\n", + "\n", + "\n", + "outer_cluster_i64-5871781006564002453\n", + "\n", + "\n", + "cluster_i64-5871781006564002453\n", + "\n", + "\n", + "\n", + "outer_cluster_i64-10912160959110460649\n", + "\n", + "\n", + "cluster_i64-10912160959110460649\n", + "\n", + "\n", + "\n", + "outer_cluster_i64-11743562013128004906\n", + "\n", + "\n", + "cluster_i64-11743562013128004906\n", + "\n", + "\n", + "\n", + "outer_cluster_i64-0\n", + "\n", + "\n", + "cluster_i64-0\n", + "\n", + "\n", + "\n", + "\n", + "Elemwise-4208978898528913939:s->ScalarDiv-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-11743562013128004906:s->i64-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-2427221081489190903:s->Tensor_shape-10964134587551653303\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-2427221081489190903:s->Int___init__-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-10964134587551653303:s->UnaryOp___call__-8391183972302725451\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-0:s->i64-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-14535344522394967184:s->Tensor_shape-3429551472952562336\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-14535344522394967184:s->IntTuple___getitem__-8609920828969388276\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-3429551472952562336:s->UnaryOp___call__-10760501220358611293\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-8609920828969388276:s->Int___init__-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-8609920828969388276:s->IntTuple___add__-3515898189561353625\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-6451836211519040652:s->Int___init__-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-6451836211519040652:s->IntTuple___add__-16058157226959687954\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-16058157226959687954:s->IntTuple___init__-15952540911656918845\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-16058157226959687954:s->IntTuple___add__-14593153318476900644\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-4208978898528913939:s->i64-4208978898528913939\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-6611095213683386216:s->Int___init__-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-6611095213683386216:s->Tensor_shape-10184707161975301700\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-10184707161975301700:s->UnaryOp___call__-10053986080337813965\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-18195398224647045558:s->Int___init__-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-18195398224647045558:s->Tensor_shape-7586556743040283621\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-7586556743040283621:s->Tensor___init__-1575189424824699418\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_var-1618856268753343266:s->String-1618856268753343266\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-7613425605146757649:s->Int___init__-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-7613425605146757649:s->Tensor_shape-5923754635005195107\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-5923754635005195107:s->BinaryOp___call__-4194065315749295272\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-14456597069198672103:s->Tensor_shape-12678910324027934471\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-14456597069198672103:s->IntTuple___getitem__-10395939792580839918\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-12678910324027934471:s->UnaryOp___call__-9097699112323522779\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-10395939792580839918:s->IntTuple___add__-5343794467401528509\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-10395939792580839918:s->IntTuple___getitem__-1906738768387841566\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-10912160959110460649:s->i64-10912160959110460649\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-5871781006564002453:s->i64-5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-14040062012979708074:s->Int___init__-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-14040062012979708074:s->Tensor_shape-3481525101393754990\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-3481525101393754990:s->UnaryOp___call__-3344968852115526449\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-5343794467401528509:s->IntTuple___init__-7690503999922668929\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-5343794467401528509:s->IntTuple___init__-9249358851075372135\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-1906738768387841566:s->Int___init__-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-1906738768387841566:s->Tensor_shape-51973628441192654\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-10514990538936846041:s->IntTuple___getitem__-14040062012979708074\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-10514990538936846041:s->Tensor_shape-5975728263446387761\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-5975728263446387761:s->UnaryOp___call__-4195639504827048526\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-3515898189561353625:s->IntTuple___add__-5343794467401528509\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-3515898189561353625:s->IntTuple___init__-7690503999922668929\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-9335705567684163424:s->Int___init__-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-9335705567684163424:s->IntTuple___init__-7690503999922668929\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-7690503999922668929:s->IntTuple___getitem__-10395939792580839918\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-51973628441192654:s->Tensor___init__-14358371401161707118\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-910243544565210939:s->Int___init__-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-910243544565210939:s->Tensor_shape-5923754635005195107\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-15952540911656918845:s->Int_var-1618856268753343266\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-5871781006564002453:s->Int___init__-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-3344968852115526449:s->Tensor___init__-14358371401161707118\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-3344968852115526449:s->Squeeze-5040379952546458196\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-9097699112323522779:s->Tensor___init__-1575189424824699418\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-9097699112323522779:s->Reduce-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-15318938057191675792:s->IntTuple___init__-5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-15318938057191675792:s->IntTuple___init__-17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-17615343019692007359:s->Int___init__-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-9249358851075372135:s->Int___init__-10912160959110460649\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor___init__-14358371401161707118:s->Tensor_shape-51973628441192654\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor___init__-14358371401161707118:s->String-6766843149853318713\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-4194065315749295272:s->Elemwise-4208978898528913939\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-4194065315749295272:s->Tensor___init__-14358371401161707118\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-4194065315749295272:s->Tensor___init__-1575189424824699418\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-4195639504827048526:s->Tensor___init__-14358371401161707118\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-4195639504827048526:s->Squeeze-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-14593153318476900644:s->IntTuple___init__-9249358851075372135\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-14593153318476900644:s->IntTuple___init__-2546176790493825425\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-2546176790493825425:s->Int___init__-4208978898528913939\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor___init__-1575189424824699418:s->Tensor_shape-7586556743040283621\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor___init__-1575189424824699418:s->String-313937328870544552\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-10053986080337813965:s->Tensor___init__-1575189424824699418\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-10053986080337813965:s->Reduce-5040379952546458196\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-8391183972302725451:s->BinaryOp___call__-4194065315749295272\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-8391183972302725451:s->Reduce-5040379952546458196\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-10760501220358611293:s->BinaryOp___call__-4194065315749295272\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-10760501220358611293:s->Reduce-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Squeeze-11743562013128004906:s->IntTuple___init__-5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-3636617994337743549:s->UnaryOp___call__-4195639504827048526\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-3636617994337743549:s->Squeeze-883374682458736911\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Squeeze-883374682458736911:s->IntTuple___init__-7690503999922668929\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-7625190977779610862:s->UnaryOp___call__-3344968852115526449\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-7625190977779610862:s->Squeeze-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-2183379458487809452:s->Tensor___init__-14358371401161707118\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-2183379458487809452:s->Squeeze-10912160959110460649\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Squeeze-10912160959110460649:s->IntTuple___add__-15318938057191675792\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-5040379952546458196:s->IntTuple___init__-17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-5040379952546458196:s->ScalarAdd-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Squeeze-5040379952546458196:s->IntTuple___init__-17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-15458927460662043536:s->UnaryOp___call__-9097699112323522779\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-15458927460662043536:s->Reduce-883374682458736911\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-883374682458736911:s->IntTuple___init__-7690503999922668929\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-883374682458736911:s->ScalarAdd-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-13202730753970051410:s->UnaryOp___call__-10053986080337813965\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-13202730753970051410:s->Reduce-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-11743562013128004906:s->IntTuple___init__-5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-11743562013128004906:s->ScalarAdd-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-593394598656903612:s->Tensor___init__-1575189424824699418\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-593394598656903612:s->Reduce-10912160959110460649\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-10912160959110460649:s->IntTuple___add__-15318938057191675792\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-10912160959110460649:s->ScalarAdd-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-7183646024568558754:s->Elemwise-4208978898528913939\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-7183646024568558754:s->UnaryOp___call__-7625190977779610862\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-7183646024568558754:s->UnaryOp___call__-13202730753970051410\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-7296576659238450322:s->BinaryOp___call__-4194065315749295272\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-7296576659238450322:s->Reduce-10912160959110460649\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-5720121267812153097:s->Reduce-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-5720121267812153097:s->BinaryOp___call__-17648236956133224341\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-17648236956133224341:s->Elemwise-4208978898528913939\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-17648236956133224341:s->UnaryOp___call__-3344968852115526449\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-17648236956133224341:s->UnaryOp___call__-10053986080337813965\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-6261542238027864055:s->Reduce-883374682458736911\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-6261542238027864055:s->BinaryOp___call__-4681938636454801376\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-4681938636454801376:s->Elemwise-4208978898528913939\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-4681938636454801376:s->UnaryOp___call__-9097699112323522779\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-4681938636454801376:s->UnaryOp___call__-4195639504827048526\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Elemwise-4208978898528913939\n", + "\n", + "\n", + "Elemwise\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ScalarDiv-0\n", + "\n", + "\n", + "ScalarDiv\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-11743562013128004906\n", + "\n", + "\n", + "Int___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "i64-11743562013128004906\n", + "\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-2427221081489190903\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-10964134587551653303\n", + "\n", + "\n", + "Tensor_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-0\n", + "\n", + "\n", + "Int___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-14535344522394967184\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-3429551472952562336\n", + "\n", + "\n", + "Tensor_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-8609920828969388276\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-6451836211519040652\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-16058157226959687954\n", + "\n", + "\n", + "IntTuple___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-4208978898528913939\n", + "\n", + "\n", + "Int___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "i64-4208978898528913939\n", + "\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-6611095213683386216\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-10184707161975301700\n", + "\n", + "\n", + "Tensor_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-18195398224647045558\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-7586556743040283621\n", + "\n", + "\n", + "Tensor_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_var-1618856268753343266\n", + "\n", + "\n", + "Int_var\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "String-1618856268753343266\n", + "\n", + "\n", + ""x_dim_0"\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-7613425605146757649\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-5923754635005195107\n", + "\n", + "\n", + "Tensor_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "i64-0\n", + "\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-14456597069198672103\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-12678910324027934471\n", + "\n", + "\n", + "Tensor_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-10395939792580839918\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-10912160959110460649\n", + "\n", + "\n", + "Int___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "i64-10912160959110460649\n", + "\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-5871781006564002453\n", + "\n", + "\n", + "Int___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "i64-5871781006564002453\n", + "\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-14040062012979708074\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-3481525101393754990\n", + "\n", + "\n", + "Tensor_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-5343794467401528509\n", + "\n", + "\n", + "IntTuple___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-1906738768387841566\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-10514990538936846041\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-5975728263446387761\n", + "\n", + "\n", + "Tensor_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-3515898189561353625\n", + "\n", + "\n", + "IntTuple___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-9335705567684163424\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-7690503999922668929\n", + "\n", + "\n", + "IntTuple___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor_shape-51973628441192654\n", + "\n", + "\n", + "Tensor_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___getitem__-910243544565210939\n", + "\n", + "\n", + "IntTuple___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-15952540911656918845\n", + "\n", + "\n", + "IntTuple___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-5871781006564002453\n", + "\n", + "\n", + "IntTuple___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-3344968852115526449\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-9097699112323522779\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-15318938057191675792\n", + "\n", + "\n", + "IntTuple___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-17615343019692007359\n", + "\n", + "\n", + "IntTuple___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-9249358851075372135\n", + "\n", + "\n", + "IntTuple___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor___init__-14358371401161707118\n", + "\n", + "\n", + "Tensor___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-4194065315749295272\n", + "\n", + "\n", + "BinaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-4195639504827048526\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___add__-14593153318476900644\n", + "\n", + "\n", + "IntTuple___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IntTuple___init__-2546176790493825425\n", + "\n", + "\n", + "IntTuple___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Tensor___init__-1575189424824699418\n", + "\n", + "\n", + "Tensor___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-10053986080337813965\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-8391183972302725451\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-10760501220358611293\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ScalarAdd-0\n", + "\n", + "\n", + "ScalarAdd\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "String-313937328870544552\n", + "\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "String-6766843149853318713\n", + "\n", + "\n", + ""y"\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Squeeze-11743562013128004906\n", + "\n", + "\n", + "Squeeze\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-3636617994337743549\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Squeeze-883374682458736911\n", + "\n", + "\n", + "Squeeze\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-7625190977779610862\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-2183379458487809452\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Squeeze-10912160959110460649\n", + "\n", + "\n", + "Squeeze\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-5040379952546458196\n", + "\n", + "\n", + "Reduce\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Squeeze-5040379952546458196\n", + "\n", + "\n", + "Squeeze\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-15458927460662043536\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-883374682458736911\n", + "\n", + "\n", + "Reduce\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-13202730753970051410\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-11743562013128004906\n", + "\n", + "\n", + "Reduce\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-593394598656903612\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Reduce-10912160959110460649\n", + "\n", + "\n", + "Reduce\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-7183646024568558754\n", + "\n", + "\n", + "BinaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-7296576659238450322\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-5720121267812153097\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-17648236956133224341\n", + "\n", + "\n", + "BinaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "UnaryOp___call__-6261542238027864055\n", + "\n", + "\n", + "UnaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "BinaryOp___call__-4681938636454801376\n", + "\n", + "\n", + "BinaryOp___call__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" ], - "source": [ - "egraph.run(20)\n", - "egraph.display(n_inline_leaves=0)" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "egraph.run(20)\n", + "egraph.display(n_inline_leaves=0)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 70 }, + "id": "xa_NKCF74p4H", + "outputId": "ab6a53d7-7862-4a54-a996-2308631a038c" + }, + "outputs": [ { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 70 - }, - "id": "xa_NKCF74p4H", - "outputId": "ab6a53d7-7862-4a54-a996-2308631a038c" - }, - "outputs": [ - { - "data": { - "text/html": [ - "
Reduce(ScalarAdd, IntTuple(Int(0)) + IntTuple(Int(2)))(\n",
-              "    Elemwise(ScalarDiv)(Tensor("x", IntTuple(Int.var("x_dim_0")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor("y", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1)))))\n",
-              ")\n",
-              "
\n" - ], - "text/latex": [ - "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", - "\\PY{n}{Reduce}\\PY{p}{(}\\PY{n}{ScalarAdd}\\PY{p}{,} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{(}\n", - " \\PY{n}{Elemwise}\\PY{p}{(}\\PY{n}{ScalarDiv}\\PY{p}{)}\\PY{p}{(}\\PY{n}{Tensor}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{x}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{,} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{x\\PYZus{}dim\\PYZus{}0}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{p}{(}\\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{5}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{7}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{Tensor}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{y}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{,} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{p}{(}\\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{5}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{p}{)}\n", - "\\end{Verbatim}\n" - ], - "text/plain": [ - "Reduce(ScalarAdd, IntTuple(Int(0)) + IntTuple(Int(2)))(\n", - " Elemwise(ScalarDiv)(Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1)))))\n", - ")" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "
Reduce(ScalarAdd, IntTuple(Int(0)) + IntTuple(Int(2)))(\n",
+       "    Elemwise(ScalarDiv)(Tensor("x", IntTuple(Int.var("x_dim_0")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor("y", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1)))))\n",
+       ")\n",
+       "
\n" ], - "source": [ - "egraph.extract(expr)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/" - }, - "id": "uVjDI5hr6fZ3", - "outputId": "4b05f145-14cc-41a5-a5e5-0a2db7019adc" - }, - "outputs": [ - { - "data": { - "text/plain": [ - "[Elemwise(ScalarDiv)(\n", - " Reduce(ScalarAdd, IntTuple(Int(0)) + IntTuple(Int(2)))(Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7))))),\n", - " Squeeze(IntTuple(Int(0)) + IntTuple(Int(2)))(Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1))))),\n", - " ),\n", - " Reduce(ScalarAdd, IntTuple(Int(0)) + IntTuple(Int(2)))(\n", - " Elemwise(ScalarDiv)(Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1)))))\n", - " ),\n", - " Reduce(ScalarAdd, IntTuple(Int(0)))(\n", - " Reduce(ScalarAdd, IntTuple(Int(2)))(\n", - " Elemwise(ScalarDiv)(\n", - " Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1))))\n", - " )\n", - " )\n", - " ),\n", - " Reduce(ScalarAdd, IntTuple(Int(1)))(\n", - " Reduce(ScalarAdd, IntTuple(Int(0)))(\n", - " Elemwise(ScalarDiv)(\n", - " Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1))))\n", - " )\n", - " )\n", - " )]" - ] - }, - "execution_count": 50, - "metadata": {}, - "output_type": "execute_result" - } + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{n}{Reduce}\\PY{p}{(}\\PY{n}{ScalarAdd}\\PY{p}{,} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{(}\n", + " \\PY{n}{Elemwise}\\PY{p}{(}\\PY{n}{ScalarDiv}\\PY{p}{)}\\PY{p}{(}\\PY{n}{Tensor}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{x}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{,} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{x\\PYZus{}dim\\PYZus{}0}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{p}{(}\\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{5}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{7}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{Tensor}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{y}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{,} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{p}{(}\\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{5}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{IntTuple}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{p}{)}\n", + "\\end{Verbatim}\n" ], - "source": [ - "egraph.extract_multiple(expr, 10)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "mw6a1kafJNax" - }, - "outputs": [], - "source": [ - "egraph.check(\n", - " eq(Sum(axis=(0, 2))(Div(x, y))).to(\n", - " # Sum(axis=0)(Mul(Sum(axis=0)(x), Squeeze(axis=0)(y)))\n", - " Div(\n", - " Sum(axis=(0, 2))(x),\n", - " Squeeze(axis=(0, 2))(y),\n", - " )\n", - " # Sum(axis=(0,))(Sum(axis=(1, 2))(y))\n", - " # Squeeze(axis=(0, 2))(y)\n", - " )\n", - ")" + "text/plain": [ + "Reduce(ScalarAdd, IntTuple(Int(0)) + IntTuple(Int(2)))(\n", + " Elemwise(ScalarDiv)(Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1)))))\n", + ")" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "id": "NgovSVpBRpu0" - }, - "outputs": [], - "source": [] + }, + "metadata": {}, + "output_type": "display_data" } - ], - "metadata": { - "mystnb": { - "execution_mode": "off" - }, + ], + "source": [ + "egraph.extract(expr)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { "colab": { - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3", - "name": "python3" + "base_uri": "https://localhost:8080/" }, - "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.10.12" + "id": "uVjDI5hr6fZ3", + "outputId": "4b05f145-14cc-41a5-a5e5-0a2db7019adc" + }, + "outputs": [ + { + "data": { + "text/plain": [ + "[Elemwise(ScalarDiv)(\n", + " Reduce(ScalarAdd, IntTuple(Int(0)) + IntTuple(Int(2)))(Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7))))),\n", + " Squeeze(IntTuple(Int(0)) + IntTuple(Int(2)))(Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1))))),\n", + " ),\n", + " Reduce(ScalarAdd, IntTuple(Int(0)) + IntTuple(Int(2)))(\n", + " Elemwise(ScalarDiv)(Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1)))))\n", + " ),\n", + " Reduce(ScalarAdd, IntTuple(Int(0)))(\n", + " Reduce(ScalarAdd, IntTuple(Int(2)))(\n", + " Elemwise(ScalarDiv)(\n", + " Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1))))\n", + " )\n", + " )\n", + " ),\n", + " Reduce(ScalarAdd, IntTuple(Int(1)))(\n", + " Reduce(ScalarAdd, IntTuple(Int(0)))(\n", + " Elemwise(ScalarDiv)(\n", + " Tensor(\"x\", IntTuple(Int.var(\"x_dim_0\")) + (IntTuple(Int(5)) + IntTuple(Int(7)))), Tensor(\"y\", IntTuple(Int(1)) + (IntTuple(Int(5)) + IntTuple(Int(1))))\n", + " )\n", + " )\n", + " )]" + ] + }, + "execution_count": 50, + "metadata": {}, + "output_type": "execute_result" } + ], + "source": [ + "egraph.extract_multiple(expr, 10)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "mw6a1kafJNax" + }, + "outputs": [], + "source": [ + "egraph.check(\n", + " eq(Sum(axis=(0, 2))(Div(x, y))).to(\n", + " # Sum(axis=0)(Mul(Sum(axis=0)(x), Squeeze(axis=0)(y)))\n", + " Div(\n", + " Sum(axis=(0, 2))(x),\n", + " Squeeze(axis=(0, 2))(y),\n", + " )\n", + " # Sum(axis=(0,))(Sum(axis=(1, 2))(y))\n", + " # Squeeze(axis=(0, 2))(y)\n", + " )\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "id": "NgovSVpBRpu0" + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "display_name": "Python 3", + "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.10.12" }, - "nbformat": 4, - "nbformat_minor": 0 + "mystnb": { + "execution_mode": "off" + } + }, + "nbformat": 4, + "nbformat_minor": 0 } diff --git a/docs/explanation/2023_11_pydata_lightning_talk.ipynb b/docs/explanation/2023_11_pydata_lightning_talk.ipynb index a0091844..5ee372a7 100644 --- a/docs/explanation/2023_11_pydata_lightning_talk.ipynb +++ b/docs/explanation/2023_11_pydata_lightning_talk.ipynb @@ -2,6 +2,7 @@ "cells": [ { "cell_type": "markdown", + "id": "7fb27b941602401d91542211134fc71a", "metadata": {}, "source": [ "```{post} 2023-11-04\n", @@ -12,6 +13,7 @@ { "cell_type": "code", "execution_count": 1, + "id": "acae54e37e7d407bbb7b55eff062a284", "metadata": { "tags": [ "hide-input" @@ -122,6 +124,7 @@ "outputs": [], "source": [ "from __future__ import annotations\n", + "\n", "from egglog import *\n", "\n", "egraph = EGraph()\n", @@ -129,19 +132,15 @@ "\n", "@egraph.class_\n", "class NDArray(Expr):\n", - " def __init__(self, i: i64Like) -> None:\n", - " ...\n", + " def __init__(self, i: i64Like) -> None: ...\n", "\n", - " def __add__(self, other: NDArray) -> NDArray:\n", - " ...\n", + " def __add__(self, other: NDArray) -> NDArray: ...\n", "\n", - " def __mul__(self, other: NDArray) -> NDArray:\n", - " ...\n", + " def __mul__(self, other: NDArray) -> NDArray: ...\n", "\n", "\n", "@egraph.function(cost=2)\n", - "def arange(i: i64Like) -> NDArray:\n", - " ...\n", + "def arange(i: i64Like) -> NDArray: ...\n", "\n", "\n", "# Register rewrite rule that asserts for all values x of type NDArray\n", @@ -6754,18 +6753,16 @@ "outputs": [], "source": [ "import timeit\n", + "\n", "import pandas as pd\n", "\n", "stmts = {\n", " \"original\": \"run_lda(X_np, y_np)\",\n", " \"numba\": \"numba_fn(X_np, y_np)\",\n", "}\n", - "df = pd.DataFrame.from_dict(\n", - " {\n", - " name: timeit.repeat(stmt, globals=globals(), number=1, repeat=10)\n", - " for name, stmt in stmts.items()\n", - " }\n", - ")" + "df = pd.DataFrame.from_dict({\n", + " name: timeit.repeat(stmt, globals=globals(), number=1, repeat=10) for name, stmt in stmts.items()\n", + "})" ] }, { @@ -6828,6 +6825,7 @@ }, { "cell_type": "markdown", + "id": "9a63283cbaf04dbcab1f6479b197f3a8", "metadata": {}, "source": [] } diff --git a/docs/explanation/pldi_2023_presentation.ipynb b/docs/explanation/pldi_2023_presentation.ipynb index 23f6920d..94acf518 100644 --- a/docs/explanation/pldi_2023_presentation.ipynb +++ b/docs/explanation/pldi_2023_presentation.ipynb @@ -1,4951 +1,4930 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```{post} 2023-08-23\n", - ":author: Saul\n", - "```\n" - ] + "cells": [ + { + "cell_type": "markdown", + "id": "7fb27b941602401d91542211134fc71a", + "metadata": {}, + "source": [ + "```{post} 2023-08-23\n", + ":author: Saul\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "a611c138-1afd-4d6f-9578-4f358d2438eb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" }, - { - "cell_type": "markdown", - "id": "a611c138-1afd-4d6f-9578-4f358d2438eb", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "```{eval-rst}\n", - "`Presentation as HTML <../pldi_2023_presentation.slides.html>`_\n", - "```\n" - ] + "tags": [] + }, + "source": [ + "```{eval-rst}\n", + "`Presentation as HTML <../pldi_2023_presentation.slides.html>`_\n", + "```\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "68dd13a3-5864-4764-a528-1eedac698723", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "68dd13a3-5864-4764-a528-1eedac698723", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "# `egglog` in Python\n", - "\n", - "In this talk I will try to cover how `egglog` in Python can:\n", - "\n", - "- Enable decentralized collaboration in the Python data science ecosystem.\n", - "- Provide a faithful authoring environment for `egglog`.\n" - ] + "tags": [] + }, + "source": [ + "# `egglog` in Python\n", + "\n", + "In this talk I will try to cover how `egglog` in Python can:\n", + "\n", + "- Enable decentralized collaboration in the Python data science ecosystem.\n", + "- Provide a faithful authoring environment for `egglog`.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "1f7b1c58-0f6f-4d43-a8b0-c04b5d2f5b08", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, + "tags": [ + "remove-input" + ] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 1, - "id": "1f7b1c58-0f6f-4d43-a8b0-c04b5d2f5b08", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [ - "remove-input" - ] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "outer_cluster_py_value_11210751155479293909_0\n", - "\n", - "\n", - "cluster_py_value_11210751155479293909_0\n", - "\n", - "\n", - "\n", - "outer_cluster_py_ndarray_17504076419467358165_0\n", - "\n", - "\n", - "cluster_py_ndarray_17504076419467358165_0\n", - "\n", - "\n", - "\n", - "outer_cluster_py_value_1976739436905633066_0\n", - "\n", - "\n", - "cluster_py_value_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "outer_cluster_py_ndarray_2781105897590886682_0\n", - "\n", - "\n", - "cluster_py_ndarray_2781105897590886682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___5871781006564002453_0\n", - "\n", - "\n", - "cluster_Values.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___0_0\n", - "\n", - "\n", - "cluster_Value.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "outer_cluster_9\n", - "\n", - "\n", - "cluster_9\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___5871781006564002453_0:s->Values.__getitem___17106626079223511235\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___5871781006564002453:s->Values.__init___5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "cross_6828067974578293639:s->arange_10912160959110460649\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "cross_6828067974578293639:s->py_ndarray_17504076419467358165\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_2781105897590886682:s->py_ndarray_2781105897590886682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_10912160959110460649:s->Values.__getitem___17106626079223511235\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_17504076419467358165:s->py_ndarray_17504076419467358165_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_value_11210751155479293909:s->py_value_11210751155479293909_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___1081172882011038115:s->Values.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___1081172882011038115:s->py_ndarray_2781105897590886682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__mul___12264044326229354243:s->py_value_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__mul___12264044326229354243:s->NDArray.__getitem___13531250035159840349\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_value_1976739436905633066:s->py_value_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___13531250035159840349:s->Values.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___13531250035159840349:s->py_ndarray_17504076419467358165\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___17106626079223511235:s->Values.__init___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___17106626079223511235:s->Value.__init___0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0:s->Value.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "py_value_11210751155479293909_0\n", - "\n", - ""x * x"\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_17504076419467358165_0\n", - "\n", - ""np.arange(x)"\n", - "\n", - "\n", - "\n", - "\n", - "py_value_1976739436905633066_0\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_2781105897590886682_0\n", - "\n", - ""np.multiply.outer(np.arange(x), np.arange(x))"\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___5871781006564002453_0\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0_0\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___5871781006564002453\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "cross_6828067974578293639\n", - "\n", - "cross\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_2781105897590886682\n", - "\n", - "py_ndarray\n", - "\n", - "\n", - "\n", - "\n", - "arange_10912160959110460649\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "py_ndarray_17504076419467358165\n", - "\n", - "py_ndarray\n", - "\n", - "\n", - "\n", - "\n", - "py_value_11210751155479293909\n", - "\n", - "py_value\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___1081172882011038115\n", - "\n", - "NDArray.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "Value.__mul___12264044326229354243\n", - "\n", - "Value.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "py_value_1976739436905633066\n", - "\n", - "py_value\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___13531250035159840349\n", - "\n", - "NDArray.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___17106626079223511235\n", - "\n", - "Values.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "outer_cluster_py_value_11210751155479293909_0\n", + "\n", + "\n", + "cluster_py_value_11210751155479293909_0\n", + "\n", + "\n", + "\n", + "outer_cluster_py_ndarray_17504076419467358165_0\n", + "\n", + "\n", + "cluster_py_ndarray_17504076419467358165_0\n", + "\n", + "\n", + "\n", + "outer_cluster_py_value_1976739436905633066_0\n", + "\n", + "\n", + "cluster_py_value_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "outer_cluster_py_ndarray_2781105897590886682_0\n", + "\n", + "\n", + "cluster_py_ndarray_2781105897590886682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___5871781006564002453_0\n", + "\n", + "\n", + "cluster_Values.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___0_0\n", + "\n", + "\n", + "cluster_Value.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "outer_cluster_9\n", + "\n", + "\n", + "cluster_9\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___5871781006564002453_0:s->Values.__getitem___17106626079223511235\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___5871781006564002453:s->Values.__init___5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "cross_6828067974578293639:s->arange_10912160959110460649\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "cross_6828067974578293639:s->py_ndarray_17504076419467358165\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_2781105897590886682:s->py_ndarray_2781105897590886682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_10912160959110460649:s->Values.__getitem___17106626079223511235\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_17504076419467358165:s->py_ndarray_17504076419467358165_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_value_11210751155479293909:s->py_value_11210751155479293909_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___1081172882011038115:s->Values.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___1081172882011038115:s->py_ndarray_2781105897590886682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__mul___12264044326229354243:s->py_value_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__mul___12264044326229354243:s->NDArray.__getitem___13531250035159840349\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_value_1976739436905633066:s->py_value_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___13531250035159840349:s->Values.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___13531250035159840349:s->py_ndarray_17504076419467358165\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___17106626079223511235:s->Values.__init___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___17106626079223511235:s->Value.__init___0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0:s->Value.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "py_value_11210751155479293909_0\n", + "\n", + ""x * x"\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_17504076419467358165_0\n", + "\n", + ""np.arange(x)"\n", + "\n", + "\n", + "\n", + "\n", + "py_value_1976739436905633066_0\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_2781105897590886682_0\n", + "\n", + ""np.multiply.outer(np.arange(x), np.arange(x))"\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___5871781006564002453_0\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0_0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___5871781006564002453\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "cross_6828067974578293639\n", + "\n", + "cross\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_2781105897590886682\n", + "\n", + "py_ndarray\n", + "\n", + "\n", + "\n", + "\n", + "arange_10912160959110460649\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "py_ndarray_17504076419467358165\n", + "\n", + "py_ndarray\n", + "\n", + "\n", + "\n", + "\n", + "py_value_11210751155479293909\n", + "\n", + "py_value\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___1081172882011038115\n", + "\n", + "NDArray.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "Value.__mul___12264044326229354243\n", + "\n", + "Value.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "py_value_1976739436905633066\n", + "\n", + "py_value\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___13531250035159840349\n", + "\n", + "NDArray.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___17106626079223511235\n", + "\n", + "Values.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "" ], - "source": [ - "from IPython.display import SVG, display\n", - "\n", - "with open(\"big_graph.svg\") as f:\n", - " display(SVG(f.read()))" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from IPython.display import SVG, display\n", + "\n", + "with open(\"big_graph.svg\") as f:\n", + " display(SVG(f.read()))" + ] + }, + { + "cell_type": "markdown", + "id": "d4ef7a6c-5fca-46ff-89d6-ab7e659f1c82", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - { - "cell_type": "markdown", - "id": "d4ef7a6c-5fca-46ff-89d6-ab7e659f1c82", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "_Saul Shanabrook @ EGRAPHS Workshop - PLDI '23_\n" - ] + "tags": [] + }, + "source": [ + "_Saul Shanabrook @ EGRAPHS Workshop - PLDI '23_\n" + ] + }, + { + "cell_type": "markdown", + "id": "72e644b5-c987-45de-87d7-ee9da885b85f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "72e644b5-c987-45de-87d7-ee9da885b85f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Open Source Data Science Ecosystem in Python\n", - "\n", - "> The term “ecosystem” is often used to describe the modern open-source scientific software. In biology, the term “ecosystem” is defined as a biological community of interacting organisms and their physical environment. Modern open-source scientific software development occurs in a similarly interconnected and interoperable fashion.\n", - "\n", - "from [Jupyter Meets the Earth: Ecosystem](https://jupytearth.org/jupyter-resources/introduction/ecosystem.html)\n", - "\n", - "![](https://jupytearth.org/_images/python-stack.png)\n" - ] + "tags": [] + }, + "source": [ + "## Open Source Data Science Ecosystem in Python\n", + "\n", + "> The term “ecosystem” is often used to describe the modern open-source scientific software. In biology, the term “ecosystem” is defined as a biological community of interacting organisms and their physical environment. Modern open-source scientific software development occurs in a similarly interconnected and interoperable fashion.\n", + "\n", + "from [Jupyter Meets the Earth: Ecosystem](https://jupytearth.org/jupyter-resources/introduction/ecosystem.html)\n", + "\n", + "![](https://jupytearth.org/_images/python-stack.png)\n" + ] + }, + { + "cell_type": "markdown", + "id": "90785f75-e933-469f-b585-127f0e4fc584", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, - { - "cell_type": "markdown", - "id": "90785f75-e933-469f-b585-127f0e4fc584", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "### Aims\n", - "\n", - "- How can the tools we build foster greater **resiliancy, collaboration, and interdependence** in this ecosystem?
\n", - "- How can they help it **stay flexible enough to adapt to the changing computational landscape** to empower users and authors?\n", - "\n", - "### What role could `egglog` play?\n", - "\n", - "- Bring the PL community closer to this space, providing theoretical frameworks for thinking about composition and language.\n", - "- Constrained type system could support decentralized interopability and composition between data science libraries.\n" - ] + "tags": [] + }, + "source": [ + "### Aims\n", + "\n", + "- How can the tools we build foster greater **resiliancy, collaboration, and interdependence** in this ecosystem?
\n", + "- How can they help it **stay flexible enough to adapt to the changing computational landscape** to empower users and authors?\n", + "\n", + "### What role could `egglog` play?\n", + "\n", + "- Bring the PL community closer to this space, providing theoretical frameworks for thinking about composition and language.\n", + "- Constrained type system could support decentralized interopability and composition between data science libraries.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "d06e53f0-6080-4e0e-b5d2-2e4140ebed72", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" }, - { - "cell_type": "code", - "execution_count": 31, - "id": "d06e53f0-6080-4e0e-b5d2-2e4140ebed72", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "from __future__ import annotations\n", - "from egglog import *" - ] + "tags": [] + }, + "outputs": [], + "source": [ + "from __future__ import annotations\n", + "\n", + "from egglog import *" + ] + }, + { + "cell_type": "markdown", + "id": "0b49d9a5-ef01-4f2b-a6f7-1bc1e5087201", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, - { - "cell_type": "markdown", - "id": "0b49d9a5-ef01-4f2b-a6f7-1bc1e5087201", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "### Other Python EGraph Libraries\n", - "\n", - "- [`riswords/quiche`](https://github.com/riswords/quiche): Optimizing Python ASTs\n", - "- [`egraphs-good/snake-egg`](https://github.com/egraphs-good/snake-egg): Generic bindings for `egg`, can bring any Python objects as expressions.\n", - "- [EGraph library added to `ibis`](https://github.com/ibis-project/ibis/pull/5781): Conversions between dataframe syntax and SQL dialects\n" - ] + "tags": [] + }, + "source": [ + "### Other Python EGraph Libraries\n", + "\n", + "- [`riswords/quiche`](https://github.com/riswords/quiche): Optimizing Python ASTs\n", + "- [`egraphs-good/snake-egg`](https://github.com/egraphs-good/snake-egg): Generic bindings for `egg`, can bring any Python objects as expressions.\n", + "- [EGraph library added to `ibis`](https://github.com/ibis-project/ibis/pull/5781): Conversions between dataframe syntax and SQL dialects\n" + ] + }, + { + "cell_type": "markdown", + "id": "c4c37446-3426-4b57-a402-2a234b54d930", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" }, - { - "cell_type": "markdown", - "id": "c4c37446-3426-4b57-a402-2a234b54d930", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "TODO: Put this first, Say it's for library authors\n", - "\n", - "Semantics of python and egglog\n" - ] + "tags": [] + }, + "source": [ + "TODO: Put this first, Say it's for library authors\n", + "\n", + "Semantics of python and egglog\n" + ] + }, + { + "cell_type": "markdown", + "id": "eadf7129-68f3-4fcc-87a4-57e064f66fc8", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "eadf7129-68f3-4fcc-87a4-57e064f66fc8", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Started with `snake-egg`\n", - "- Didn't want to re-invent the wheel, stay abreast of recent developments and research\n", - "- Second piece that interests me\n", - " - Unlike `egg` there are some builtin sorts, and can build user defined sorts on top of those\n", - " - No host language conditions or data structures\n", - " - Helps with optimization, more constrained\n", - " - -> De-centers algorithms based on value, move to based on type. Everything becomes an interface.\n", - " - Social dynamics, goal is ability to inovate and experiment, while still supporting existing use cases\n", - " - New dataframe library comes out, supporting custom hardware. How dow we use it without rewriting code?\n", - " - How do we have healthy ecosystem within these tools? Power\n", - " - If it's too hard, encourages centralized monopolistic actors to step in provide one stop shop solutions for users.\n", - " - Active problem in the community, with things like trying to standardize on interop.\n", - " - Before getting too abstract, let's go to an example\n" - ] + "tags": [] + }, + "source": [ + "- Started with `snake-egg`\n", + "- Didn't want to re-invent the wheel, stay abreast of recent developments and research\n", + "- Second piece that interests me\n", + " - Unlike `egg` there are some builtin sorts, and can build user defined sorts on top of those\n", + " - No host language conditions or data structures\n", + " - Helps with optimization, more constrained\n", + " - -> De-centers algorithms based on value, move to based on type. Everything becomes an interface.\n", + " - Social dynamics, goal is ability to inovate and experiment, while still supporting existing use cases\n", + " - New dataframe library comes out, supporting custom hardware. How dow we use it without rewriting code?\n", + " - How do we have healthy ecosystem within these tools? Power\n", + " - If it's too hard, encourages centralized monopolistic actors to step in provide one stop shop solutions for users.\n", + " - Active problem in the community, with things like trying to standardize on interop.\n", + " - Before getting too abstract, let's go to an example\n" + ] + }, + { + "cell_type": "markdown", + "id": "a037bf31-2637-470a-ae26-b56538f689a6", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "a037bf31-2637-470a-ae26-b56538f689a6", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### A story about Arrays\n" - ] + "tags": [] + }, + "source": [ + "### A story about Arrays\n" + ] + }, + { + "cell_type": "markdown", + "id": "082d9334-86e2-42a1-92f4-08563902b064", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "082d9334-86e2-42a1-92f4-08563902b064", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- This is one path through a huge maze of use cases.\n", - "- Does not represent one killer example, but is an area I am familar with based on my previous work\n" - ] + "tags": [] + }, + "source": [ + "- This is one path through a huge maze of use cases.\n", + "- Does not represent one killer example, but is an area I am familar with based on my previous work\n" + ] + }, + { + "cell_type": "markdown", + "id": "24955a1a-d3d6-44d8-a7ee-b5a87bd2a153", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, - { - "cell_type": "markdown", - "id": "24955a1a-d3d6-44d8-a7ee-b5a87bd2a153", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "source": [ - "#### 1. Someone makes an NDArray library...\n" - ] + "tags": [] + }, + "source": [ + "#### 1. Someone makes an NDArray library...\n" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "be2f1cb2-81c1-485d-8eb9-06c4d8b3c6ba", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - { - "cell_type": "code", - "execution_count": 32, - "id": "be2f1cb2-81c1-485d-8eb9-06c4d8b3c6ba", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "ndarray_mod = Module()\n", - "..." - ] + "tags": [] + }, + "outputs": [], + "source": [ + "ndarray_mod = Module()" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "b0d83999-9aac-4881-a81a-385541b621fb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" }, - { - "cell_type": "code", - "execution_count": 33, - "id": "b0d83999-9aac-4881-a81a-385541b621fb", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "@ndarray_mod.class_\n", - "class Value(Expr):\n", - " def __init__(self, v: i64Like) -> None:\n", - " ...\n", - "\n", - " def __mul__(self, other: Value) -> Value:\n", - " ...\n", - "\n", - " def __add__(self, other: Value) -> Value:\n", - " ...\n", - "\n", - "\n", - "i, j = vars_(\"i j\", i64)\n", - "ndarray_mod.register(\n", - " rewrite(Value(i) * Value(j)).to(Value(i * j)),\n", - " rewrite(Value(i) + Value(j)).to(Value(i + j)),\n", - ")\n", - "\n", - "\n", - "@ndarray_mod.class_\n", - "class Values(Expr):\n", - " def __init__(self, v: Vec[Value]) -> None:\n", - " ...\n", - "\n", - " def __getitem__(self, idx: Value) -> Value:\n", - " ...\n", - "\n", - " def length(self) -> Value:\n", - " ...\n", - "\n", - " def concat(self, other: Values) -> Values:\n", - " ...\n", - "\n", - "\n", - "@ndarray_mod.register\n", - "def _values(vs: Vec[Value], other: Vec[Value]):\n", - " yield rewrite(Values(vs)[Value(i)]).to(vs[i])\n", - " yield rewrite(Values(vs).length()).to(Value(vs.length()))\n", - " yield rewrite(Values(vs).concat(Values(other))).to(Values(vs.append(other)))" - ] + "tags": [] + }, + "outputs": [], + "source": [ + "@ndarray_mod.class_\n", + "class Value(Expr):\n", + " def __init__(self, v: i64Like) -> None: ...\n", + "\n", + " def __mul__(self, other: Value) -> Value: ...\n", + "\n", + " def __add__(self, other: Value) -> Value: ...\n", + "\n", + "\n", + "i, j = vars_(\"i j\", i64)\n", + "ndarray_mod.register(\n", + " rewrite(Value(i) * Value(j)).to(Value(i * j)),\n", + " rewrite(Value(i) + Value(j)).to(Value(i + j)),\n", + ")\n", + "\n", + "\n", + "@ndarray_mod.class_\n", + "class Values(Expr):\n", + " def __init__(self, v: Vec[Value]) -> None: ...\n", + "\n", + " def __getitem__(self, idx: Value) -> Value: ...\n", + "\n", + " def length(self) -> Value: ...\n", + "\n", + " def concat(self, other: Values) -> Values: ...\n", + "\n", + "\n", + "@ndarray_mod.register\n", + "def _values(vs: Vec[Value], other: Vec[Value]):\n", + " yield rewrite(Values(vs)[Value(i)]).to(vs[i])\n", + " yield rewrite(Values(vs).length()).to(Value(vs.length()))\n", + " yield rewrite(Values(vs).concat(Values(other))).to(Values(vs.append(other)))" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "0a9c6dfd-21b6-4e28-abe4-1bc8d8229a5a", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - { - "cell_type": "code", - "execution_count": 34, - "id": "0a9c6dfd-21b6-4e28-abe4-1bc8d8229a5a", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "@ndarray_mod.class_\n", - "class NDArray(Expr):\n", - " def __getitem__(self, idx: Values) -> Value:\n", - " ...\n", - "\n", - " def shape(self) -> Values:\n", - " ...\n", - "\n", - "\n", - "@ndarray_mod.function\n", - "def arange(n: Value) -> NDArray:\n", - " ..." - ] + "tags": [] + }, + "outputs": [], + "source": [ + "@ndarray_mod.class_\n", + "class NDArray(Expr):\n", + " def __getitem__(self, idx: Values) -> Value: ...\n", + "\n", + " def shape(self) -> Values: ...\n", + "\n", + "\n", + "@ndarray_mod.function\n", + "def arange(n: Value) -> NDArray: ..." + ] + }, + { + "cell_type": "markdown", + "id": "36dd2603-c60e-42d0-a5d5-98043ed307a5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "36dd2603-c60e-42d0-a5d5-98043ed307a5", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Basic\n", - "- One function, range, get shape and index into array\n", - "- Very different from existing paradigms in Python... Inheritance, multi-dispatch, dunder protocols.\n", - " - Entirely open protocol.\n", - " - Anyone else could define ways to create arrays\n", - " - About mathematical definition really. This is from M\n" - ] + "tags": [] + }, + "source": [ + "- Basic\n", + "- One function, range, get shape and index into array\n", + "- Very different from existing paradigms in Python... Inheritance, multi-dispatch, dunder protocols.\n", + " - Entirely open protocol.\n", + " - Anyone else could define ways to create arrays\n", + " - About mathematical definition really. This is from M\n" + ] + }, + { + "attachments": {}, + "cell_type": "markdown", + "id": "0f36b591-9a20-4405-80cb-3dbfea11b129", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - { - "attachments": {}, - "cell_type": "markdown", - "id": "0f36b591-9a20-4405-80cb-3dbfea11b129", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "Restifo Mullin, Lenore Marie, \"A mathematics of arrays\" (1988). _Electrical Engineering and Computer Science - Dissertations_. 249.\n" - ] + "tags": [] + }, + "source": [ + "Restifo Mullin, Lenore Marie, \"A mathematics of arrays\" (1988). _Electrical Engineering and Computer Science - Dissertations_. 249.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "3e020ae8-29a3-4e35-8510-aa2639c87701", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - { - "cell_type": "code", - "execution_count": 35, - "id": "3e020ae8-29a3-4e35-8510-aa2639c87701", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "@ndarray_mod.register\n", - "def _(n: Value, idx: Values, a: NDArray):\n", - " yield rewrite(arange(n).shape()).to(Values(Vec(n)))\n", - " yield rewrite(arange(n)[idx]).to(idx[Value(0)])" - ] + "tags": [] + }, + "outputs": [], + "source": [ + "@ndarray_mod.register\n", + "def _(n: Value, idx: Values, a: NDArray):\n", + " yield rewrite(arange(n).shape()).to(Values(Vec(n)))\n", + " yield rewrite(arange(n)[idx]).to(idx[Value(0)])" + ] + }, + { + "cell_type": "markdown", + "id": "81562baf-da04-4734-bc79-b0aedf11ab02", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "81562baf-da04-4734-bc79-b0aedf11ab02", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Rules to compute shape and index into arange.\n" - ] + "tags": [] + }, + "source": [ + "- Rules to compute shape and index into arange.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 38, + "id": "d46c1977-fa8c-4410-90c6-619ef3659a87", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 38, - "id": "d46c1977-fa8c-4410-90c6-619ef3659a87", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___0_0\n", - "\n", - "\n", - "cluster_Values.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0:s->Values.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453:s->arange_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682_0\n", - "\n", - "10\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "ten_0\n", - "\n", - "ten\n", - "\n", - "\n", - "\n", - "\n", - "arange_0\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453\n", - "\n", - "NDArray.shape\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___0_0\n", - "\n", - "\n", - "cluster_Values.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0:s->Values.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453:s->arange_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682_0\n", - "\n", - "10\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "ten_0\n", - "\n", - "ten\n", - "\n", - "\n", - "\n", - "\n", - "arange_0\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453\n", - "\n", - "NDArray.shape\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[Module(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'arange': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()),), return_type=TypeRefWithVars(name='NDArray', args=()), var_arg_type=None)}, _classes={'Value': ClassDecl(methods={'__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), '__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0), 'Values': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'length': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()),), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'concat': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Values', args=())), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='Vec', args=(TypeRefWithVars(name='Value', args=()),)),), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0), 'NDArray': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()), TypeRefWithVars(name='Values', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'shape': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()),), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={}, class_variables={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Value.__init__': {ClassMethodRef(class_name='Value', method_name='__init__')}, 'Value.__mul__': {MethodRef(class_name='Value', method_name='__mul__')}, 'Value.__add__': {MethodRef(class_name='Value', method_name='__add__')}, '!=': {MethodRef(class_name='Value', method_name='__ne__'), MethodRef(class_name='NDArray', method_name='__ne__'), MethodRef(class_name='Values', method_name='__ne__')}, 'Values.__init__': {ClassMethodRef(class_name='Values', method_name='__init__')}, 'Values.__getitem__': {MethodRef(class_name='Values', method_name='__getitem__')}, 'Values.length': {MethodRef(class_name='Values', method_name='length')}, 'Values.concat': {MethodRef(class_name='Values', method_name='concat')}, 'NDArray.__getitem__': {MethodRef(class_name='NDArray', method_name='__getitem__')}, 'NDArray.shape': {MethodRef(class_name='NDArray', method_name='shape')}, 'arange': {FunctionRef(name='arange')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Value', method_name='__init__'): 'Value.__init__', MethodRef(class_name='Value', method_name='__mul__'): 'Value.__mul__', MethodRef(class_name='Value', method_name='__add__'): 'Value.__add__', MethodRef(class_name='Value', method_name='__ne__'): '!=', ClassMethodRef(class_name='Values', method_name='__init__'): 'Values.__init__', MethodRef(class_name='Values', method_name='__getitem__'): 'Values.__getitem__', MethodRef(class_name='Values', method_name='length'): 'Values.length', MethodRef(class_name='Values', method_name='concat'): 'Values.concat', MethodRef(class_name='Values', method_name='__ne__'): '!=', MethodRef(class_name='NDArray', method_name='__getitem__'): 'NDArray.__getitem__', MethodRef(class_name='NDArray', method_name='shape'): 'NDArray.shape', MethodRef(class_name='NDArray', method_name='__ne__'): '!=', FunctionRef(name='arange'): 'arange'}, _egg_sort_to_type_ref={'Value': JustTypeRef(name='Value', args=()), 'Values': JustTypeRef(name='Values', args=()), 'Vec[Value]': JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)), 'NDArray': JustTypeRef(name='NDArray', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Value', args=()): 'Value', JustTypeRef(name='Values', args=()): 'Values', JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)): 'Vec[Value]', JustTypeRef(name='NDArray', args=()): 'NDArray'})))], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "Values(Vec.empty().push(Value(10)))" - ] - }, - "execution_count": 38, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___0_0\n", + "\n", + "\n", + "cluster_Values.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0:s->Values.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453:s->arange_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682_0\n", + "\n", + "10\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "ten_0\n", + "\n", + "ten\n", + "\n", + "\n", + "\n", + "\n", + "arange_0\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453\n", + "\n", + "NDArray.shape\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph = EGraph([ndarray_mod])\n", - "ten = egraph.let(\"ten\", arange(Value(10)))\n", - "ten_shape = ten.shape()\n", - "egraph.register(ten_shape)\n", - "\n", - "egraph.run(20)\n", - "egraph.display()\n", - "egraph.extract(ten_shape)" - ] - }, - { - "cell_type": "code", - "execution_count": 41, - "id": "7a0d38d8-085a-4c61-ab23-06247c7171ef", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "cluster_Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___0_0\n", - "\n", - "\n", - "cluster_Value.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___0_0\n", - "\n", - "\n", - "cluster_Values.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906_0:s->Values.__getitem___520482313101349337\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453:s->arange_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0:s->Values.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906:s->Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939:s->Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835:s->Values.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835:s->ten_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337:s->Values.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337:s->Value.__init___0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0:s->Value.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682_0\n", - "\n", - "10\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0_0\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939_0\n", - "\n", - "7\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906_0\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453\n", - "\n", - "NDArray.shape\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "arange_0\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "ten_0\n", - "\n", - "ten\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835\n", - "\n", - "NDArray.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337\n", - "\n", - "Values.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "cluster_Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "cluster_Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Value.__init___0_0\n", - "\n", - "\n", - "cluster_Value.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Values.__init___0_0\n", - "\n", - "\n", - "cluster_Values.__init___0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906_0:s->Values.__getitem___520482313101349337\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453:s->arange_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0:s->Values.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906:s->Values.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "arange_0:s->Value.__init___3377577844511369682\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939:s->Value.__init___4208978898528913939_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835:s->Values.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835:s->ten_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337:s->Values.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337:s->Value.__init___0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0:s->Value.__init___0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682_0\n", - "\n", - "10\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0_0\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939_0\n", - "\n", - "7\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0_0\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906_0\n", - "\n", - "Vec[Value]\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.shape_5871781006564002453\n", - "\n", - "NDArray.shape\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___0\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Values.__init___11743562013128004906\n", - "\n", - "Values.__init__\n", - "\n", - "\n", - "\n", - "\n", - "arange_0\n", - "\n", - "arange\n", - "\n", - "\n", - "\n", - "\n", - "ten_0\n", - "\n", - "ten\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___3377577844511369682\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___4208978898528913939\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n", - "NDArray.__getitem___11868447927124751835\n", - "\n", - "NDArray.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "Values.__getitem___520482313101349337\n", - "\n", - "Values.__getitem__\n", - "\n", - "\n", - "\n", - "\n", - "Value.__init___0\n", - "\n", - "Value.__init__\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[Module(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'arange': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()),), return_type=TypeRefWithVars(name='NDArray', args=()), var_arg_type=None)}, _classes={'Value': ClassDecl(methods={'__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), '__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0), 'Values': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'length': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()),), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'concat': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Values', args=())), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='Vec', args=(TypeRefWithVars(name='Value', args=()),)),), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0), 'NDArray': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()), TypeRefWithVars(name='Values', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'shape': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()),), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={}, class_variables={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Value.__init__': {ClassMethodRef(class_name='Value', method_name='__init__')}, 'Value.__mul__': {MethodRef(class_name='Value', method_name='__mul__')}, 'Value.__add__': {MethodRef(class_name='Value', method_name='__add__')}, '!=': {MethodRef(class_name='Value', method_name='__ne__'), MethodRef(class_name='NDArray', method_name='__ne__'), MethodRef(class_name='Values', method_name='__ne__')}, 'Values.__init__': {ClassMethodRef(class_name='Values', method_name='__init__')}, 'Values.__getitem__': {MethodRef(class_name='Values', method_name='__getitem__')}, 'Values.length': {MethodRef(class_name='Values', method_name='length')}, 'Values.concat': {MethodRef(class_name='Values', method_name='concat')}, 'NDArray.__getitem__': {MethodRef(class_name='NDArray', method_name='__getitem__')}, 'NDArray.shape': {MethodRef(class_name='NDArray', method_name='shape')}, 'arange': {FunctionRef(name='arange')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Value', method_name='__init__'): 'Value.__init__', MethodRef(class_name='Value', method_name='__mul__'): 'Value.__mul__', MethodRef(class_name='Value', method_name='__add__'): 'Value.__add__', MethodRef(class_name='Value', method_name='__ne__'): '!=', ClassMethodRef(class_name='Values', method_name='__init__'): 'Values.__init__', MethodRef(class_name='Values', method_name='__getitem__'): 'Values.__getitem__', MethodRef(class_name='Values', method_name='length'): 'Values.length', MethodRef(class_name='Values', method_name='concat'): 'Values.concat', MethodRef(class_name='Values', method_name='__ne__'): '!=', MethodRef(class_name='NDArray', method_name='__getitem__'): 'NDArray.__getitem__', MethodRef(class_name='NDArray', method_name='shape'): 'NDArray.shape', MethodRef(class_name='NDArray', method_name='__ne__'): '!=', FunctionRef(name='arange'): 'arange'}, _egg_sort_to_type_ref={'Value': JustTypeRef(name='Value', args=()), 'Values': JustTypeRef(name='Values', args=()), 'Vec[Value]': JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)), 'NDArray': JustTypeRef(name='NDArray', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Value', args=()): 'Value', JustTypeRef(name='Values', args=()): 'Values', JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)): 'Vec[Value]', JustTypeRef(name='NDArray', args=()): 'NDArray'})))], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'vec-empty': set(), 'Value.__init__': set(), 'vec-push': set(), 'Values.__init__': set(), 'arange': set(), 'NDArray.__getitem__': set()}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [ - "Value(7)" - ] - }, - "execution_count": 41, - "metadata": {}, - "output_type": "execute_result" - } + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___0_0\n", + "\n", + "\n", + "cluster_Values.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0:s->Values.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453:s->arange_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682_0\n", + "\n", + "10\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "ten_0\n", + "\n", + "ten\n", + "\n", + "\n", + "\n", + "\n", + "arange_0\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453\n", + "\n", + "NDArray.shape\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "ten_indexed = ten[Values(Vec(Value(7)))]\n", - "egraph.register(ten_indexed)\n", - "\n", - "egraph.run(20)\n", - "\n", - "egraph.display()\n", - "egraph.extract(ten_indexed)" - ] - }, - { - "cell_type": "markdown", - "id": "956f439e-80e6-4ff3-adb2-52a784ee5902", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Any user can try it now\n" - ] - }, - { - "cell_type": "markdown", - "id": "07bece32-f436-4c6b-8d8a-21305673b376", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### 2. Someone else decides to implement a cross product library\n" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "0eecf615-36c1-44a6-b122-743f66bc997f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "cross_mod = Module([ndarray_mod])\n", - "\n", - "\n", - "@cross_mod.function\n", - "def cross(l: NDArray, r: NDArray) -> NDArray:\n", - " ...\n", - "\n", - "\n", - "@cross_mod.register\n", - "def _cross(l: NDArray, r: NDArray, idx: Values):\n", - " yield rewrite(cross(l, r).shape()).to(l.shape().concat(r.shape()))\n", - " yield rewrite(cross(l, r)[idx]).to(l[idx] * r[idx])" + "text/plain": [ + "EGraph(_flatted_deps=[Module(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'arange': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()),), return_type=TypeRefWithVars(name='NDArray', args=()), var_arg_type=None)}, _classes={'Value': ClassDecl(methods={'__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), '__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0), 'Values': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'length': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()),), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'concat': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Values', args=())), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='Vec', args=(TypeRefWithVars(name='Value', args=()),)),), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0), 'NDArray': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()), TypeRefWithVars(name='Values', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'shape': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()),), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={}, class_variables={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Value.__init__': {ClassMethodRef(class_name='Value', method_name='__init__')}, 'Value.__mul__': {MethodRef(class_name='Value', method_name='__mul__')}, 'Value.__add__': {MethodRef(class_name='Value', method_name='__add__')}, '!=': {MethodRef(class_name='Value', method_name='__ne__'), MethodRef(class_name='NDArray', method_name='__ne__'), MethodRef(class_name='Values', method_name='__ne__')}, 'Values.__init__': {ClassMethodRef(class_name='Values', method_name='__init__')}, 'Values.__getitem__': {MethodRef(class_name='Values', method_name='__getitem__')}, 'Values.length': {MethodRef(class_name='Values', method_name='length')}, 'Values.concat': {MethodRef(class_name='Values', method_name='concat')}, 'NDArray.__getitem__': {MethodRef(class_name='NDArray', method_name='__getitem__')}, 'NDArray.shape': {MethodRef(class_name='NDArray', method_name='shape')}, 'arange': {FunctionRef(name='arange')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Value', method_name='__init__'): 'Value.__init__', MethodRef(class_name='Value', method_name='__mul__'): 'Value.__mul__', MethodRef(class_name='Value', method_name='__add__'): 'Value.__add__', MethodRef(class_name='Value', method_name='__ne__'): '!=', ClassMethodRef(class_name='Values', method_name='__init__'): 'Values.__init__', MethodRef(class_name='Values', method_name='__getitem__'): 'Values.__getitem__', MethodRef(class_name='Values', method_name='length'): 'Values.length', MethodRef(class_name='Values', method_name='concat'): 'Values.concat', MethodRef(class_name='Values', method_name='__ne__'): '!=', MethodRef(class_name='NDArray', method_name='__getitem__'): 'NDArray.__getitem__', MethodRef(class_name='NDArray', method_name='shape'): 'NDArray.shape', MethodRef(class_name='NDArray', method_name='__ne__'): '!=', FunctionRef(name='arange'): 'arange'}, _egg_sort_to_type_ref={'Value': JustTypeRef(name='Value', args=()), 'Values': JustTypeRef(name='Values', args=()), 'Vec[Value]': JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)), 'NDArray': JustTypeRef(name='NDArray', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Value', args=()): 'Value', JustTypeRef(name='Values', args=()): 'Values', JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)): 'Vec[Value]', JustTypeRef(name='NDArray', args=()): 'NDArray'})))], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "id": "d1a60f2d-5669-4c05-be64-68f525eae9e4", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Someone decides to add some functionality\n", - "- Multiplicative cross product\n", - "- Shape is concatation, index is product of each matrix at that index\n", - "- Mathematical definition\n" + "data": { + "text/plain": [ + "Values(Vec.empty().push(Value(10)))" ] + }, + "execution_count": 38, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph([ndarray_mod])\n", + "ten = egraph.let(\"ten\", arange(Value(10)))\n", + "ten_shape = ten.shape()\n", + "egraph.register(ten_shape)\n", + "\n", + "egraph.run(20)\n", + "egraph.display()\n", + "egraph.extract(ten_shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "7a0d38d8-085a-4c61-ab23-06247c7171ef", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 22, - "id": "a7127ee6-2d17-4460-942a-b303277d8f81", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Values(Vec.empty().push(Value(11)).push(Value(10)))" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "cluster_Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___0_0\n", + "\n", + "\n", + "cluster_Value.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___0_0\n", + "\n", + "\n", + "cluster_Values.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906_0:s->Values.__getitem___520482313101349337\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453:s->arange_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0:s->Values.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906:s->Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939:s->Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835:s->Values.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835:s->ten_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337:s->Values.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337:s->Value.__init___0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0:s->Value.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682_0\n", + "\n", + "10\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0_0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939_0\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906_0\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453\n", + "\n", + "NDArray.shape\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "arange_0\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "ten_0\n", + "\n", + "ten\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835\n", + "\n", + "NDArray.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337\n", + "\n", + "Values.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph = EGraph([cross_mod])\n", - "egraph.simplify(cross(arange(Value(10)), arange(Value(11))).shape(), 10)" + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "cluster_Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "cluster_Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Value.__init___0_0\n", + "\n", + "\n", + "cluster_Value.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Values.__init___0_0\n", + "\n", + "\n", + "cluster_Values.__init___0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906_0:s->Values.__getitem___520482313101349337\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453:s->arange_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0:s->Values.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906:s->Values.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "arange_0:s->Value.__init___3377577844511369682\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682:s->Value.__init___3377577844511369682_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939:s->Value.__init___4208978898528913939_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835:s->Values.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835:s->ten_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337:s->Values.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337:s->Value.__init___0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0:s->Value.__init___0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682_0\n", + "\n", + "10\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0_0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939_0\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0_0\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906_0\n", + "\n", + "Vec[Value]\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.shape_5871781006564002453\n", + "\n", + "NDArray.shape\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___0\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Values.__init___11743562013128004906\n", + "\n", + "Values.__init__\n", + "\n", + "\n", + "\n", + "\n", + "arange_0\n", + "\n", + "arange\n", + "\n", + "\n", + "\n", + "\n", + "ten_0\n", + "\n", + "ten\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___3377577844511369682\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___4208978898528913939\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n", + "NDArray.__getitem___11868447927124751835\n", + "\n", + "NDArray.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "Values.__getitem___520482313101349337\n", + "\n", + "Values.__getitem__\n", + "\n", + "\n", + "\n", + "\n", + "Value.__init___0\n", + "\n", + "Value.__init__\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/plain": [ + "EGraph(_flatted_deps=[Module(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={'arange': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()),), return_type=TypeRefWithVars(name='NDArray', args=()), var_arg_type=None)}, _classes={'Value': ClassDecl(methods={'__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), '__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Value', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0), 'Values': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Value', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'length': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()),), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'concat': FunctionDecl(arg_types=(TypeRefWithVars(name='Values', args=()), TypeRefWithVars(name='Values', args=())), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={'__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='Vec', args=(TypeRefWithVars(name='Value', args=()),)),), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0), 'NDArray': ClassDecl(methods={'__getitem__': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()), TypeRefWithVars(name='Values', args=())), return_type=TypeRefWithVars(name='Value', args=()), var_arg_type=None), 'shape': FunctionDecl(arg_types=(TypeRefWithVars(name='NDArray', args=()),), return_type=TypeRefWithVars(name='Values', args=()), var_arg_type=None)}, class_methods={}, class_variables={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Value.__init__': {ClassMethodRef(class_name='Value', method_name='__init__')}, 'Value.__mul__': {MethodRef(class_name='Value', method_name='__mul__')}, 'Value.__add__': {MethodRef(class_name='Value', method_name='__add__')}, '!=': {MethodRef(class_name='Value', method_name='__ne__'), MethodRef(class_name='NDArray', method_name='__ne__'), MethodRef(class_name='Values', method_name='__ne__')}, 'Values.__init__': {ClassMethodRef(class_name='Values', method_name='__init__')}, 'Values.__getitem__': {MethodRef(class_name='Values', method_name='__getitem__')}, 'Values.length': {MethodRef(class_name='Values', method_name='length')}, 'Values.concat': {MethodRef(class_name='Values', method_name='concat')}, 'NDArray.__getitem__': {MethodRef(class_name='NDArray', method_name='__getitem__')}, 'NDArray.shape': {MethodRef(class_name='NDArray', method_name='shape')}, 'arange': {FunctionRef(name='arange')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Value', method_name='__init__'): 'Value.__init__', MethodRef(class_name='Value', method_name='__mul__'): 'Value.__mul__', MethodRef(class_name='Value', method_name='__add__'): 'Value.__add__', MethodRef(class_name='Value', method_name='__ne__'): '!=', ClassMethodRef(class_name='Values', method_name='__init__'): 'Values.__init__', MethodRef(class_name='Values', method_name='__getitem__'): 'Values.__getitem__', MethodRef(class_name='Values', method_name='length'): 'Values.length', MethodRef(class_name='Values', method_name='concat'): 'Values.concat', MethodRef(class_name='Values', method_name='__ne__'): '!=', MethodRef(class_name='NDArray', method_name='__getitem__'): 'NDArray.__getitem__', MethodRef(class_name='NDArray', method_name='shape'): 'NDArray.shape', MethodRef(class_name='NDArray', method_name='__ne__'): '!=', FunctionRef(name='arange'): 'arange'}, _egg_sort_to_type_ref={'Value': JustTypeRef(name='Value', args=()), 'Values': JustTypeRef(name='Values', args=()), 'Vec[Value]': JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)), 'NDArray': JustTypeRef(name='NDArray', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Value', args=()): 'Value', JustTypeRef(name='Values', args=()): 'Values', JustTypeRef(name='Vec', args=(JustTypeRef(name='Value', args=()),)): 'Vec[Value]', JustTypeRef(name='NDArray', args=()): 'NDArray'})))], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'vec-empty': set(), 'Value.__init__': set(), 'vec-push': set(), 'Values.__init__': set(), 'arange': set(), 'NDArray.__getitem__': set()}), _callable_ref_to_egg_fn={}, _egg_sort_to_type_ref={}, _type_ref_to_egg_sort={})))" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "id": "944b5b6c-7583-4c75-a740-0d75a835c522", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### 3. I write my wonderful data science application using it\n" + "data": { + "text/plain": [ + "Value(7)" ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "ten_indexed = ten[Values(Vec(Value(7)))]\n", + "egraph.register(ten_indexed)\n", + "\n", + "egraph.run(20)\n", + "\n", + "egraph.display()\n", + "egraph.extract(ten_indexed)" + ] + }, + { + "cell_type": "markdown", + "id": "956f439e-80e6-4ff3-adb2-52a784ee5902", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "code", - "execution_count": 23, - "id": "14fde972-d358-4324-bc1e-35b3591184cc", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Value(100)" - ] - }, - "execution_count": 23, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "def my_special_app(x: Value) -> Value:\n", - " return cross(arange(x), arange(x))[Values(Vec(x))]\n", - "\n", - "\n", - "egraph = EGraph([cross_mod])\n", - "\n", - "egraph.simplify(my_special_app(Value(10)), 10)" - ] + "tags": [] + }, + "source": [ + "- Any user can try it now\n" + ] + }, + { + "cell_type": "markdown", + "id": "07bece32-f436-4c6b-8d8a-21305673b376", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "9f39ea1c-689d-4f5c-9fc3-bb8bd79e44f7", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Different person installs cross module\n", - "- Implements application using their complicated algorithm\n" - ] + "tags": [] + }, + "source": [ + "#### 2. Someone else decides to implement a cross product library\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "0eecf615-36c1-44a6-b122-743f66bc997f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - { - "cell_type": "markdown", - "id": "6967505c-48f0-45ad-837e-b6f2fdc99921", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - ".... but its too slow...\n" - ] + "tags": [] + }, + "outputs": [], + "source": [ + "cross_mod = Module([ndarray_mod])\n", + "\n", + "\n", + "@cross_mod.function\n", + "def cross(l: NDArray, r: NDArray) -> NDArray: ...\n", + "\n", + "\n", + "@cross_mod.register\n", + "def _cross(l: NDArray, r: NDArray, idx: Values):\n", + " yield rewrite(cross(l, r).shape()).to(l.shape().concat(r.shape()))\n", + " yield rewrite(cross(l, r)[idx]).to(l[idx] * r[idx])" + ] + }, + { + "cell_type": "markdown", + "id": "d1a60f2d-5669-4c05-be64-68f525eae9e4", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "code", - "execution_count": 24, - "id": "12a435f1-5059-43d0-8a22-001bcf2ce19f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "for i in range(100):\n", - " egraph.simplify(my_special_app(Value(i)), 10)" - ] + "tags": [] + }, + "source": [ + "- Someone decides to add some functionality\n", + "- Multiplicative cross product\n", + "- Shape is concatation, index is product of each matrix at that index\n", + "- Mathematical definition\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "a7127ee6-2d17-4460-942a-b303277d8f81", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "06d04938-f7db-4094-a249-e778d199c3db", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Too slow in inner loop\n", - "- Is there a way we could optimize it\n" + "data": { + "text/plain": [ + "Values(Vec.empty().push(Value(11)).push(Value(10)))" ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph([cross_mod])\n", + "egraph.simplify(cross(arange(Value(10)), arange(Value(11))).shape(), 10)" + ] + }, + { + "cell_type": "markdown", + "id": "944b5b6c-7583-4c75-a740-0d75a835c522", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "8ba13f96-2333-43fd-a467-c18cf0daa9e4", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### 4. Someone else writes a library for delayed execution\n" - ] + "tags": [] + }, + "source": [ + "#### 3. I write my wonderful data science application using it\n" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "14fde972-d358-4324-bc1e-35b3591184cc", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 25, - "id": "17e9ad75-f829-4a0c-bf8f-e9047cd0e177", - "metadata": { - "editable": true, - "scrolled": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "Ellipsis" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "py_mod = Module([ndarray_mod])\n", - "\n", - "\n", - "@py_mod.function\n", - "def py_value(s: StringLike) -> Value:\n", - " ...\n", - "\n", - "\n", - "..." + "data": { + "text/plain": [ + "Value(100)" ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def my_special_app(x: Value) -> Value:\n", + " return cross(arange(x), arange(x))[Values(Vec(x))]\n", + "\n", + "\n", + "egraph = EGraph([cross_mod])\n", + "\n", + "egraph.simplify(my_special_app(Value(10)), 10)" + ] + }, + { + "cell_type": "markdown", + "id": "9f39ea1c-689d-4f5c-9fc3-bb8bd79e44f7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "51cf4880-4576-40a7-8648-491218534d8f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- While this is happening, someone else, based on the original module, wrote a different execution semantics\n", - "- Builds up expression string instead of trying to evaluate eagerly\n" - ] + "tags": [] + }, + "source": [ + "- Different person installs cross module\n", + "- Implements application using their complicated algorithm\n" + ] + }, + { + "cell_type": "markdown", + "id": "6967505c-48f0-45ad-837e-b6f2fdc99921", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - { - "cell_type": "code", - "execution_count": 26, - "id": "5ce8398b-ffac-4bc9-bb53-52c039f35093", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "@py_mod.register\n", - "def _py_value(l: String, r: String):\n", - " yield rewrite(py_value(l) + py_value(r)).to(py_value(join(l, \" + \", r)))\n", - " yield rewrite(py_value(l) * py_value(r)).to(py_value(join(l, \" * \", r)))\n", - "\n", - "\n", - "@py_mod.function\n", - "def py_values(s: StringLike) -> Values:\n", - " ...\n", - "\n", - "\n", - "@py_mod.register\n", - "def _py_values(l: String, r: String):\n", - " yield rewrite(py_values(l)[py_value(r)]).to(py_value(join(l, \"[\", r, \"]\")))\n", - " yield rewrite(py_values(l).length()).to(py_value(join(\"len(\", l, \")\")))\n", - " yield rewrite(py_values(l).concat(py_values(r))).to(py_values(join(l, \" + \", r)))\n", - "\n", - "\n", - "@py_mod.function\n", - "def py_ndarray(s: StringLike) -> NDArray:\n", - " ...\n", - "\n", - "\n", - "@py_mod.register\n", - "def _py_ndarray(l: String, r: String):\n", - " yield rewrite(py_ndarray(l)[py_values(r)]).to(py_value(join(l, \"[\", r, \"]\")))\n", - " yield rewrite(py_ndarray(l).shape()).to(py_values(join(l, \".shape\")))\n", - " yield rewrite(arange(py_value(l))).to(py_ndarray(join(\"np.arange(\", l, \")\")))" - ] + "tags": [] + }, + "source": [ + ".... but its too slow...\n" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "12a435f1-5059-43d0-8a22-001bcf2ce19f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - { - "cell_type": "markdown", - "id": "85e7ceba-65f2-4766-8673-2d4dfa5bab96", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### 5. I can use it jit compile my application!\n" - ] + "tags": [] + }, + "outputs": [], + "source": [ + "for i in range(100):\n", + " egraph.simplify(my_special_app(Value(i)), 10)" + ] + }, + { + "cell_type": "markdown", + "id": "06d04938-f7db-4094-a249-e778d199c3db", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "code", - "execution_count": 27, - "id": "96bb493e-74a1-41a1-911e-a67ac31d92e5", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "py_value(\"x * x\")" - ] - }, - "execution_count": 27, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "egraph = EGraph([cross_mod, py_mod])\n", - "egraph.simplify(my_special_app(py_value(\"x\")), 10)" - ] + "tags": [] + }, + "source": [ + "- Too slow in inner loop\n", + "- Is there a way we could optimize it\n" + ] + }, + { + "cell_type": "markdown", + "id": "8ba13f96-2333-43fd-a467-c18cf0daa9e4", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "5e9b8c74-42df-409c-ac74-66c605e46035", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- I pull in third party library\n", - "- Add it to my e-graph\n", - "- Now I can compile lazily\n", - "- py_mod never needed to know about cross product, works with it\n" - ] + "tags": [] + }, + "source": [ + "#### 4. Someone else writes a library for delayed execution\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "17e9ad75-f829-4a0c-bf8f-e9047cd0e177", + "metadata": { + "editable": true, + "scrolled": true, + "slideshow": { + "slide_type": "fragment" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "b5abc145-33bf-4093-ae7d-5dd4a60bc6ae", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "source": [ - "... and add support for jit compilation for the other library I am using, without changing either library:\n" + "data": { + "text/plain": [ + "Ellipsis" ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "py_mod = Module([ndarray_mod])\n", + "\n", + "\n", + "@py_mod.function\n", + "def py_value(s: StringLike) -> Value: ..." + ] + }, + { + "cell_type": "markdown", + "id": "51cf4880-4576-40a7-8648-491218534d8f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "code", - "execution_count": 28, - "id": "14cec5ba-b96e-46ef-853a-ddbe4ccfb37f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "@egraph.register\n", - "def _(l: String, r: String):\n", - " yield rewrite(cross(py_ndarray(l), py_ndarray(r))).to(py_ndarray(join(\"np.multiply.outer(\", l, \", \", r, \")\")))" - ] + "tags": [] + }, + "source": [ + "- While this is happening, someone else, based on the original module, wrote a different execution semantics\n", + "- Builds up expression string instead of trying to evaluate eagerly\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "5ce8398b-ffac-4bc9-bb53-52c039f35093", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" }, - { - "cell_type": "code", - "execution_count": 42, - "id": "10190128-8d45-4722-8977-4855a0e44be9", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "skip" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'big_graph.svg'" - ] - }, - "execution_count": 42, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "egraph.run(20)\n", - "egraph.graphviz().render(outfile=\"big_graph.svg\", format=\"svg\")" - ] + "tags": [] + }, + "outputs": [], + "source": [ + "@py_mod.register\n", + "def _py_value(l: String, r: String):\n", + " yield rewrite(py_value(l) + py_value(r)).to(py_value(join(l, \" + \", r)))\n", + " yield rewrite(py_value(l) * py_value(r)).to(py_value(join(l, \" * \", r)))\n", + "\n", + "\n", + "@py_mod.function\n", + "def py_values(s: StringLike) -> Values: ...\n", + "\n", + "\n", + "@py_mod.register\n", + "def _py_values(l: String, r: String):\n", + " yield rewrite(py_values(l)[py_value(r)]).to(py_value(join(l, \"[\", r, \"]\")))\n", + " yield rewrite(py_values(l).length()).to(py_value(join(\"len(\", l, \")\")))\n", + " yield rewrite(py_values(l).concat(py_values(r))).to(py_values(join(l, \" + \", r)))\n", + "\n", + "\n", + "@py_mod.function\n", + "def py_ndarray(s: StringLike) -> NDArray: ...\n", + "\n", + "\n", + "@py_mod.register\n", + "def _py_ndarray(l: String, r: String):\n", + " yield rewrite(py_ndarray(l)[py_values(r)]).to(py_value(join(l, \"[\", r, \"]\")))\n", + " yield rewrite(py_ndarray(l).shape()).to(py_values(join(l, \".shape\")))\n", + " yield rewrite(arange(py_value(l))).to(py_ndarray(join(\"np.arange(\", l, \")\")))" + ] + }, + { + "cell_type": "markdown", + "id": "85e7ceba-65f2-4766-8673-2d4dfa5bab96", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "193b6cf7-01b1-4446-8664-04d622fb0070", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "#### Takeaways...\n", - "\n", - "_...from this totally realistic example._\n", - "\n", - "- Declerative nature of `egglog` could facilitate decantralized library collaboration and experimentation.\n", - " - Focus on types over values for library authors encourages interoperability.\n", - "- Pushing power down, empowering users and library authors\n", - "- Could allow greater collaboration between PL community and data science library community in Python\n" - ] + "tags": [] + }, + "source": [ + "#### 5. I can use it jit compile my application!\n" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "96bb493e-74a1-41a1-911e-a67ac31d92e5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "2daa57bf-0078-4edf-a4bf-a6586bd56968", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## How does it work?\n" + "data": { + "text/plain": [ + "py_value(\"x * x\")" ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph([cross_mod, py_mod])\n", + "egraph.simplify(my_special_app(py_value(\"x\")), 10)" + ] + }, + { + "cell_type": "markdown", + "id": "5e9b8c74-42df-409c-ac74-66c605e46035", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "54f61359-111b-45f8-b7b2-e54d21aa2ccd", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Will show how some examples translate\n" - ] + "tags": [] + }, + "source": [ + "- I pull in third party library\n", + "- Add it to my e-graph\n", + "- Now I can compile lazily\n", + "- py_mod never needed to know about cross product, works with it\n" + ] + }, + { + "cell_type": "markdown", + "id": "b5abc145-33bf-4093-ae7d-5dd4a60bc6ae", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" }, - { - "cell_type": "markdown", - "id": "673a0c32-2b21-431e-b5fc-6d8b29abf6a5", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "source": [ - "### Sorts, expressions, and functions\n" - ] + "tags": [] + }, + "source": [ + "... and add support for jit compilation for the other library I am using, without changing either library:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "14cec5ba-b96e-46ef-853a-ddbe4ccfb37f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" }, - { - "cell_type": "code", - "execution_count": 3, - "id": "33d34134-78c9-472b-b364-479c3aca3b23", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "outer_cluster_Var_1976739436905633066_0\n", - "\n", - "\n", - "cluster_Var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896:s->Var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896:s->Num_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453:s->Var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_13095445380246898500:s->Mul_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_13095445380246898500:s->Num_16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906:s->Num_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_1976739436905633066:s->Var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359:s->Add_7659469028595837896\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359:s->Num_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102:s->Num_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_1976739436905633066_0\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359_0\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102_0\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906_0\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "Add_13095445380246898500\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "Var_1976739436905633066\n", - "\n", - "Var\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%egglog graph\n", - "(datatype Math\n", - " (Num i64)\n", - " (Var String)\n", - " (Add Math Math)\n", - " (Mul Math Math))\n", - "\n", - "(define expr1 (Mul (Num 2) (Add (Var \"x\") (Num 3))))\n", - "(define expr2 (Add (Num 6) (Mul (Num 2) (Var \"x\"))))" - ] + "tags": [] + }, + "outputs": [], + "source": [ + "@egraph.register\n", + "def _(l: String, r: String):\n", + " yield rewrite(cross(py_ndarray(l), py_ndarray(r))).to(py_ndarray(join(\"np.multiply.outer(\", l, \", \", r, \")\")))" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "10190128-8d45-4722-8977-4855a0e44be9", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "skip" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "markdown", - "id": "1c0f4ee3-f5bd-49e7-b2a6-81088809eb08", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- User defined sorts\n", - "- Expressions\n", - " - expr1 and expr2 in their own e-classes, we haven't ran any rules\n", - "- `%%egglog` magic, Writing egglog in Notebook, graphs, output inline.\n" + "data": { + "text/plain": [ + "'big_graph.svg'" ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.run(20)\n", + "egraph.graphviz().render(outfile=\"big_graph.svg\", format=\"svg\")" + ] + }, + { + "cell_type": "markdown", + "id": "193b6cf7-01b1-4446-8664-04d622fb0070", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "code", - "execution_count": 4, - "id": "4c774ee4-722c-4a3a-b61b-37733b435948", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.var_1976739436905633066_0\n", - "\n", - "\n", - "cluster_Num.var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500:s->Num.__init___16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066:s->Num.var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__add___7659469028595837896\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102_0\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066_0\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066\n", - "\n", - "Num.var\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.var_1976739436905633066_0\n", - "\n", - "\n", - "cluster_Num.var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_7\n", - "\n", - "\n", - "cluster_7\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_5\n", - "\n", - "\n", - "cluster_5\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500:s->Num.__init___16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066:s->Num.var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__add___7659469028595837896\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102_0\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066_0\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___13095445380246898500\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066\n", - "\n", - "Num.var\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'var': FunctionDecl(arg_types=(TypeRefWithVars(name='String', args=()),), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.var': {ClassMethodRef(class_name='Num', method_name='var')}, 'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, 'Num.__mul__': {MethodRef(class_name='Num', method_name='__mul__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='var'): 'Num.var', ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__mul__'): 'Num.__mul__', MethodRef(class_name='Num', method_name='__ne__'): '!='}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "egraph = EGraph()\n", - "\n", - "\n", - "@egraph.class_\n", - "class Num(Expr):\n", - " @classmethod\n", - " def var(cls, name: StringLike) -> Num:\n", - " ...\n", - "\n", - " def __init__(self, value: i64Like) -> None:\n", - " ...\n", - "\n", - " def __add__(self, other: Num) -> Num:\n", - " ...\n", - "\n", - " def __mul__(self, other: Num) -> Num:\n", - " ...\n", - "\n", - "\n", - "expr1 = egraph.let(\"expr1\", Num(2) * (Num.var(\"x\") + Num(3)))\n", - "expr2 = egraph.let(\"expr2\", Num(6) + Num(2) * Num.var(\"x\"))\n", - "egraph" - ] + "tags": [] + }, + "source": [ + "#### Takeaways...\n", + "\n", + "_...from this totally realistic example._\n", + "\n", + "- Declerative nature of `egglog` could facilitate decantralized library collaboration and experimentation.\n", + " - Focus on types over values for library authors encourages interoperability.\n", + "- Pushing power down, empowering users and library authors\n", + "- Could allow greater collaboration between PL community and data science library community in Python\n" + ] + }, + { + "cell_type": "markdown", + "id": "2daa57bf-0078-4edf-a4bf-a6586bd56968", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "1e32a7c4-fbb7-4dd2-8af1-c7fd22a3ca86", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Re-use existing Python class and functions\n", - " - Humans and computers to understand the typing semantics\n", - " - Humans read `__init__` and `__add__`.\n", - " - Static type checkers. `Num(\"String\")` it won't work.\n", - " - Static type checking drives much of the API design of the library\n", - "- Operator overloading support infix operators\n", - "- Names generated based on classes\n", - " - Same operator on different types compile to different function with different signature\n" - ] + "tags": [] + }, + "source": [ + "## How does it work?\n" + ] + }, + { + "cell_type": "markdown", + "id": "54f61359-111b-45f8-b7b2-e54d21aa2ccd", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "6efa3a03-cce0-4075-a767-84da0a7aec86", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Rewrite rules and checks\n" - ] + "tags": [] + }, + "source": [ + "- Will show how some examples translate\n" + ] + }, + { + "cell_type": "markdown", + "id": "673a0c32-2b21-431e-b5fc-6d8b29abf6a5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" + }, + "tags": [] + }, + "source": [ + "### Sorts, expressions, and functions\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "33d34134-78c9-472b-b364-479c3aca3b23", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 5, - "id": "99cb645c-f006-4e9e-bc39-762be3fa5d61", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_8\n", - "\n", - "\n", - "cluster_8\n", - "\n", - "\n", - "\n", - "outer_cluster_Var_1976739436905633066_0\n", - "\n", - "\n", - "cluster_Var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num_11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896:s->Var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896:s->Num_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7784354942592584825:s->Var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_7784354942592584825:s->Num_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906:s->Num_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_1976739436905633066:s->Var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359:s->Add_7784354942592584825\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_16545935510313822457:s->Mul_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_16545935510313822457:s->Mul_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_5000171696738118755:s->Mul_5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Add_5000171696738118755:s->Num_16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359:s->Num_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453:s->Var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102:s->Num_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_11743562013128004906:s->Num_11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Mul_11743562013128004906:s->Num_17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Var_1976739436905633066_0\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359_0\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102_0\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906_0\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "Add_7659469028595837896\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "Add_7784354942592584825\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "Num_11743562013128004906\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "Var_1976739436905633066\n", - "\n", - "Var\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "Mul_17615343019692007359\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "Add_16545935510313822457\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "Add_5000171696738118755\n", - "\n", - "Add\n", - "\n", - "\n", - "\n", - "\n", - "Num_17615343019692007359\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "Mul_5871781006564002453\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n", - "Num_16783941965674463102\n", - "\n", - "Num\n", - "\n", - "\n", - "\n", - "\n", - "Mul_11743562013128004906\n", - "\n", - "Mul\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "outer_cluster_Var_1976739436905633066_0\n", + "\n", + "\n", + "cluster_Var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896:s->Var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896:s->Num_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453:s->Var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_13095445380246898500:s->Mul_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_13095445380246898500:s->Num_16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906:s->Num_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_1976739436905633066:s->Var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359:s->Add_7659469028595837896\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359:s->Num_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102:s->Num_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_1976739436905633066_0\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359_0\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102_0\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906_0\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "Add_13095445380246898500\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "Var_1976739436905633066\n", + "\n", + "Var\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "%%egglog graph continue\n", - "(rewrite (Add a b)\n", - " (Add b a))\n", - "(rewrite (Mul a (Add b c))\n", - " (Add (Mul a b) (Mul a c)))\n", - "(rewrite (Add (Num a) (Num b))\n", - " (Num (+ a b)))\n", - "(rewrite (Mul (Num a) (Num b))\n", - " (Num (* a b)))\n", - "\n", - "(run 10)\n", - "(check (= expr1 expr2))" + "text/plain": [ + "" ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%egglog graph\n", + "(datatype Math\n", + " (Num i64)\n", + " (Var String)\n", + " (Add Math Math)\n", + " (Mul Math Math))\n", + "\n", + "(define expr1 (Mul (Num 2) (Add (Var \"x\") (Num 3))))\n", + "(define expr2 (Add (Num 6) (Mul (Num 2) (Var \"x\"))))" + ] + }, + { + "cell_type": "markdown", + "id": "1c0f4ee3-f5bd-49e7-b2a6-81088809eb08", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "0f5ef7d7-e043-40ee-a334-2e9b34a7b33f", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- See equivalent, in same e-class now\n" - ] + "tags": [] + }, + "source": [ + "- User defined sorts\n", + "- Expressions\n", + " - expr1 and expr2 in their own e-classes, we haven't ran any rules\n", + "- `%%egglog` magic, Writing egglog in Notebook, graphs, output inline.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4c774ee4-722c-4a3a-b61b-37733b435948", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 6, - "id": "a7f568af-5655-4926-bb93-5c2415f267cb", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_10\n", - "\n", - "\n", - "cluster_10\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.var_1976739436905633066_0\n", - "\n", - "\n", - "cluster_Num.var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066:s->Num.var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__add___7784354942592584825\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747:s->Num.__init___16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015:s->Num.__mul___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102_0\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066_0\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066\n", - "\n", - "Num.var\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_0\n", - "\n", - "\n", - "cluster_0\n", - "\n", - "\n", - "\n", - "outer_cluster_1\n", - "\n", - "\n", - "cluster_1\n", - "\n", - "\n", - "\n", - "outer_cluster_4\n", - "\n", - "\n", - "cluster_4\n", - "\n", - "\n", - "\n", - "outer_cluster_6\n", - "\n", - "\n", - "cluster_6\n", - "\n", - "\n", - "\n", - "outer_cluster_10\n", - "\n", - "\n", - "cluster_10\n", - "\n", - "\n", - "\n", - "outer_cluster_3\n", - "\n", - "\n", - "cluster_3\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "cluster_Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "cluster_Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "cluster_Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_Num.var_1976739436905633066_0\n", - "\n", - "\n", - "cluster_Num.var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066:s->Num.var_1976739436905633066_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359:s->Num.__add___7784354942592584825\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747:s->Num.__init___16783941965674463102\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015:s->Num.__mul___5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015:s->Num.__mul___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906:s->Num.__init___11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825:s->Num.__init___17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825:s->Num.var_1976739436905633066\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359_0\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102_0\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906_0\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066_0\n", - "\n", - ""x"\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___17615343019692007359\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___11743562013128004906\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.var_1976739436905633066\n", - "\n", - "Num.var\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___17615343019692007359\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "expr2_0\n", - "\n", - "expr2\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___9842753449732275747\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___11849178328430774015\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "expr1_0\n", - "\n", - "expr1\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___5871781006564002453\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__mul___11743562013128004906\n", - "\n", - "Num.__mul__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__init___16783941965674463102\n", - "\n", - "Num.__init__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7659469028595837896\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n", - "Num.__add___7784354942592584825\n", - "\n", - "Num.__add__\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'var': FunctionDecl(arg_types=(TypeRefWithVars(name='String', args=()),), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.var': {ClassMethodRef(class_name='Num', method_name='var')}, 'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, 'Num.__mul__': {MethodRef(class_name='Num', method_name='__mul__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='var'): 'Num.var', ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__mul__'): 'Num.__mul__', MethodRef(class_name='Num', method_name='__ne__'): '!='}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.var_1976739436905633066_0\n", + "\n", + "\n", + "cluster_Num.var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500:s->Num.__init___16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066:s->Num.var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__add___7659469028595837896\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102_0\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066_0\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066\n", + "\n", + "Num.var\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.var_1976739436905633066_0\n", + "\n", + "\n", + "cluster_Num.var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_7\n", + "\n", + "\n", + "cluster_7\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_5\n", + "\n", + "\n", + "cluster_5\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500:s->Num.__init___16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066:s->Num.var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__add___7659469028595837896\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102_0\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066_0\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___13095445380246898500\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066\n", + "\n", + "Num.var\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "@egraph.register\n", - "def _(a: Num, b: Num, c: Num, i: i64, j: i64):\n", - " yield rewrite(a + b).to(b + a)\n", - " yield rewrite(a * (b + c)).to((a * b) + (a * c))\n", - " yield rewrite(Num(i) + Num(j)).to(Num(i + j))\n", - " yield rewrite(Num(i) * Num(j)).to(Num(i * j))\n", - "\n", - "\n", - "egraph.run(10)\n", - "egraph.check(eq(expr1).to(expr2))\n", - "egraph" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'var': FunctionDecl(arg_types=(TypeRefWithVars(name='String', args=()),), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.var': {ClassMethodRef(class_name='Num', method_name='var')}, 'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, 'Num.__mul__': {MethodRef(class_name='Num', method_name='__mul__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='var'): 'Num.var', ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__mul__'): 'Num.__mul__', MethodRef(class_name='Num', method_name='__ne__'): '!='}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph = EGraph()\n", + "\n", + "\n", + "@egraph.class_\n", + "class Num(Expr):\n", + " @classmethod\n", + " def var(cls, name: StringLike) -> Num: ...\n", + "\n", + " def __init__(self, value: i64Like) -> None: ...\n", + "\n", + " def __add__(self, other: Num) -> Num: ...\n", + "\n", + " def __mul__(self, other: Num) -> Num: ...\n", + "\n", + "\n", + "expr1 = egraph.let(\"expr1\", Num(2) * (Num.var(\"x\") + Num(3)))\n", + "expr2 = egraph.let(\"expr2\", Num(6) + Num(2) * Num.var(\"x\"))\n", + "egraph" + ] + }, + { + "cell_type": "markdown", + "id": "1e32a7c4-fbb7-4dd2-8af1-c7fd22a3ca86", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "208b3db5-e2d7-48f8-afaf-e637c132691e", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Similar in Python, rewrite rules, run, check\n", - "- Notice that all vars need types, unlike inferred in egglog\n", - " - Both for static type checkers to verify\n", - " - And for runtime to know what methods\n" - ] + "tags": [] + }, + "source": [ + "- Re-use existing Python class and functions\n", + " - Humans and computers to understand the typing semantics\n", + " - Humans read `__init__` and `__add__`.\n", + " - Static type checkers. `Num(\"String\")` it won't work.\n", + " - Static type checking drives much of the API design of the library\n", + "- Operator overloading support infix operators\n", + "- Names generated based on classes\n", + " - Same operator on different types compile to different function with different signature\n" + ] + }, + { + "cell_type": "markdown", + "id": "6efa3a03-cce0-4075-a767-84da0a7aec86", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "cd095e65-074d-44d1-b180-060aa34a92d7", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Extracting lowest cost expression\n" - ] + "tags": [] + }, + "source": [ + "### Rewrite rules and checks\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "99cb645c-f006-4e9e-bc39-762be3fa5d61", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 7, - "id": "33644682-1e44-4d30-9ed8-9126ff00582b", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "Extracted with cost 8: (Add (Mul (Num 2) (Var \"x\")) (Num 6))\n" - ] - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_8\n", + "\n", + "\n", + "cluster_8\n", + "\n", + "\n", + "\n", + "outer_cluster_Var_1976739436905633066_0\n", + "\n", + "\n", + "cluster_Var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num_11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896:s->Var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896:s->Num_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7784354942592584825:s->Var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_7784354942592584825:s->Num_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906:s->Num_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_1976739436905633066:s->Var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359:s->Add_7784354942592584825\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_16545935510313822457:s->Mul_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_16545935510313822457:s->Mul_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_5000171696738118755:s->Mul_5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Add_5000171696738118755:s->Num_16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359:s->Num_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453:s->Var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102:s->Num_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_11743562013128004906:s->Num_11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Mul_11743562013128004906:s->Num_17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Var_1976739436905633066_0\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359_0\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102_0\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906_0\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "Add_7659469028595837896\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "Add_7784354942592584825\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "Num_11743562013128004906\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "Var_1976739436905633066\n", + "\n", + "Var\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "Mul_17615343019692007359\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "Add_16545935510313822457\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "Add_5000171696738118755\n", + "\n", + "Add\n", + "\n", + "\n", + "\n", + "\n", + "Num_17615343019692007359\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "Mul_5871781006564002453\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n", + "Num_16783941965674463102\n", + "\n", + "Num\n", + "\n", + "\n", + "\n", + "\n", + "Mul_11743562013128004906\n", + "\n", + "Mul\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "%%egglog continue output\n", - "(extract expr1)" + "text/plain": [ + "" ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%egglog graph continue\n", + "(rewrite (Add a b)\n", + " (Add b a))\n", + "(rewrite (Mul a (Add b c))\n", + " (Add (Mul a b) (Mul a c)))\n", + "(rewrite (Add (Num a) (Num b))\n", + " (Num (+ a b)))\n", + "(rewrite (Mul (Num a) (Num b))\n", + " (Num (* a b)))\n", + "\n", + "(run 10)\n", + "(check (= expr1 expr2))" + ] + }, + { + "cell_type": "markdown", + "id": "0f5ef7d7-e043-40ee-a334-2e9b34a7b33f", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "b8932052-014c-4e93-b3f3-b8e112b77811", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Extract lowest cost expr\n" - ] + "tags": [] + }, + "source": [ + "- See equivalent, in same e-class now\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a7f568af-5655-4926-bb93-5c2415f267cb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 8, - "id": "63308ba8-f31a-4809-bf4a-c6816cbcdc00", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "text/plain": [ - "(Num(2) * Num.var(\"x\")) + Num(6)" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_10\n", + "\n", + "\n", + "cluster_10\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.var_1976739436905633066_0\n", + "\n", + "\n", + "cluster_Num.var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066:s->Num.var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__add___7784354942592584825\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747:s->Num.__init___16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015:s->Num.__mul___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102_0\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066_0\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066\n", + "\n", + "Num.var\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n" + ], + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_0\n", + "\n", + "\n", + "cluster_0\n", + "\n", + "\n", + "\n", + "outer_cluster_1\n", + "\n", + "\n", + "cluster_1\n", + "\n", + "\n", + "\n", + "outer_cluster_4\n", + "\n", + "\n", + "cluster_4\n", + "\n", + "\n", + "\n", + "outer_cluster_6\n", + "\n", + "\n", + "cluster_6\n", + "\n", + "\n", + "\n", + "outer_cluster_10\n", + "\n", + "\n", + "cluster_10\n", + "\n", + "\n", + "\n", + "outer_cluster_3\n", + "\n", + "\n", + "cluster_3\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "cluster_Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "cluster_Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "cluster_Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_Num.var_1976739436905633066_0\n", + "\n", + "\n", + "cluster_Num.var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359:s->Num.__init___17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906:s->Num.__init___11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066:s->Num.var_1976739436905633066_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359:s->Num.__add___7784354942592584825\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747:s->Num.__init___16783941965674463102\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015:s->Num.__mul___5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015:s->Num.__mul___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906:s->Num.__init___11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102:s->Num.__init___16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825:s->Num.__init___17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825:s->Num.var_1976739436905633066\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359_0\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102_0\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906_0\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066_0\n", + "\n", + ""x"\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___17615343019692007359\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___11743562013128004906\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.var_1976739436905633066\n", + "\n", + "Num.var\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___17615343019692007359\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "expr2_0\n", + "\n", + "expr2\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___9842753449732275747\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___11849178328430774015\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "expr1_0\n", + "\n", + "expr1\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___5871781006564002453\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__mul___11743562013128004906\n", + "\n", + "Num.__mul__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__init___16783941965674463102\n", + "\n", + "Num.__init__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7659469028595837896\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n", + "Num.__add___7784354942592584825\n", + "\n", + "Num.__add__\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "egraph.extract(expr1)" + "text/plain": [ + "EGraph(_flatted_deps=[], _mod_decls=ModuleDeclarations(_decl=Declarations(_functions={}, _classes={'Num': ClassDecl(methods={'__add__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__mul__': FunctionDecl(arg_types=(TypeRefWithVars(name='Num', args=()), TypeRefWithVars(name='Num', args=())), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_methods={'var': FunctionDecl(arg_types=(TypeRefWithVars(name='String', args=()),), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None), '__init__': FunctionDecl(arg_types=(TypeRefWithVars(name='i64', args=()),), return_type=TypeRefWithVars(name='Num', args=()), var_arg_type=None)}, class_variables={}, n_type_vars=0)}, _constants={}, _egg_fn_to_callable_refs=defaultdict(, {'Num.var': {ClassMethodRef(class_name='Num', method_name='var')}, 'Num.__init__': {ClassMethodRef(class_name='Num', method_name='__init__')}, 'Num.__add__': {MethodRef(class_name='Num', method_name='__add__')}, 'Num.__mul__': {MethodRef(class_name='Num', method_name='__mul__')}, '!=': {MethodRef(class_name='Num', method_name='__ne__')}}), _callable_ref_to_egg_fn={ClassMethodRef(class_name='Num', method_name='var'): 'Num.var', ClassMethodRef(class_name='Num', method_name='__init__'): 'Num.__init__', MethodRef(class_name='Num', method_name='__add__'): 'Num.__add__', MethodRef(class_name='Num', method_name='__mul__'): 'Num.__mul__', MethodRef(class_name='Num', method_name='__ne__'): '!='}, _egg_sort_to_type_ref={'Num': JustTypeRef(name='Num', args=())}, _type_ref_to_egg_sort={JustTypeRef(name='Num', args=()): 'Num'})))" ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "@egraph.register\n", + "def _(a: Num, b: Num, c: Num, i: i64, j: i64):\n", + " yield rewrite(a + b).to(b + a)\n", + " yield rewrite(a * (b + c)).to((a * b) + (a * c))\n", + " yield rewrite(Num(i) + Num(j)).to(Num(i + j))\n", + " yield rewrite(Num(i) * Num(j)).to(Num(i * j))\n", + "\n", + "\n", + "egraph.run(10)\n", + "egraph.check(eq(expr1).to(expr2))\n", + "egraph" + ] + }, + { + "cell_type": "markdown", + "id": "208b3db5-e2d7-48f8-afaf-e637c132691e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "386bb340-06a1-4c86-88ba-33201d4214ca", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- get back expr object\n", - "- Str representation is Python syntax\n" - ] + "tags": [] + }, + "source": [ + "- Similar in Python, rewrite rules, run, check\n", + "- Notice that all vars need types, unlike inferred in egglog\n", + " - Both for static type checkers to verify\n", + " - And for runtime to know what methods\n" + ] + }, + { + "cell_type": "markdown", + "id": "cd095e65-074d-44d1-b180-060aa34a92d7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "f5e0d729-028a-4af4-947f-62a2e109d28a", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Multipart Rules\n" - ] + "tags": [] + }, + "source": [ + "### Extracting lowest cost expression\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "33644682-1e44-4d30-9ed8-9126ff00582b", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 9, - "id": "0bea7d72-bf5c-47c4-95ac-e2926ad33cf3", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0_0\n", - "\n", - "\n", - "cluster_fib_0_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_0\n", - "\n", - "\n", - "cluster_fib_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "cluster_fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453\n", - "\n", - "\n", - "cluster_fib_5871781006564002453\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_4208978898528913939_0\n", - "\n", - "\n", - "cluster_fib_4208978898528913939_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_10912160959110460649\n", - "\n", - "\n", - "cluster_fib_10912160959110460649\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_10080759905092916392_0\n", - "\n", - "\n", - "cluster_fib_10080759905092916392_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "cluster_fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_17615343019692007359\n", - "\n", - "\n", - "cluster_fib_17615343019692007359\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_10912160959110460649_0\n", - "\n", - "\n", - "cluster_fib_10912160959110460649_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_4208978898528913939\n", - "\n", - "\n", - "cluster_fib_4208978898528913939\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_10080759905092916392\n", - "\n", - "\n", - "cluster_fib_10080759905092916392\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_16783941965674463102\n", - "\n", - "\n", - "cluster_fib_16783941965674463102\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "cluster_fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_16783941965674463102_0\n", - "\n", - "\n", - "cluster_fib_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_11743562013128004906\n", - "\n", - "\n", - "cluster_fib_11743562013128004906\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5040379952546458196\n", - "\n", - "\n", - "cluster_fib_5040379952546458196\n", - "\n", - "\n", - "\n", - "outer_cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "cluster_fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "fib_16783941965674463102:s->fib_16783941965674463102_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906:s->fib_11743562013128004906_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196:s->fib_5040379952546458196_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359:s->fib_17615343019692007359_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_0:s->fib_0_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_4208978898528913939:s->fib_4208978898528913939_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10080759905092916392:s->fib_10080759905092916392_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453:s->fib_5871781006564002453_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_10912160959110460649:s->fib_10912160959110460649_0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "fib_16783941965674463102\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "fib_16783941965674463102_value\n", - "\n", - "8\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_0\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "fib_16783941965674463102_0\n", - "\n", - "6\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "fib_11743562013128004906_value\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_0\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_value\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "fib_10080759905092916392_0\n", - "\n", - "8\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_0\n", - "\n", - "3\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "fib_17615343019692007359_value\n", - "\n", - "2\n", - "\n", - "\n", - "\n", - "\n", - "fib_0\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "fib_0_value\n", - "\n", - "0\n", - "\n", - "\n", - "\n", - "\n", - "fib_10912160959110460649_0\n", - "\n", - "5\n", - "\n", - "\n", - "\n", - "\n", - "fib_4208978898528913939\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "fib_4208978898528913939_value\n", - "\n", - "13\n", - "\n", - "\n", - "\n", - "\n", - "fib_10080759905092916392\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "fib_10080759905092916392_value\n", - "\n", - "21\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_0\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "fib_5040379952546458196_0\n", - "\n", - "4\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "fib_5871781006564002453_value\n", - "\n", - "1\n", - "\n", - "\n", - "\n", - "\n", - "fib_4208978898528913939_0\n", - "\n", - "7\n", - "\n", - "\n", - "\n", - "\n", - "fib_10912160959110460649\n", - "\n", - "fib\n", - "\n", - "\n", - "\n", - "\n", - "fib_10912160959110460649_value\n", - "\n", - "5\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%egglog graph\n", - "(function fib (i64) i64)\n", - "\n", - "(set (fib 0) 0)\n", - "(set (fib 1) 1)\n", - "(rule ((= f0 (fib x))\n", - " (= f1 (fib (+ x 1))))\n", - " ((set (fib (+ x 2)) (+ f0 f1))))\n", - "\n", - "(run 7)\n", - "(check (= (fib 7) 13))" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "Extracted with cost 8: (Add (Mul (Num 2) (Var \"x\")) (Num 6))\n" + ] + } + ], + "source": [ + "%%egglog continue output\n", + "(extract expr1)" + ] + }, + { + "cell_type": "markdown", + "id": "b8932052-014c-4e93-b3f3-b8e112b77811", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "2dc964ef-f5ee-4b7c-80a5-5a11b848ece7", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Rule that depend on facts and execute actions\n" - ] + "tags": [] + }, + "source": [ + "- Extract lowest cost expr\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "63308ba8-f31a-4809-bf4a-c6816cbcdc00", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 10, - "id": "7f4bd927-ccd6-4240-aec0-123d93a782c5", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "fib_egraph = EGraph()\n", - "\n", - "\n", - "@fib_egraph.function\n", - "def fib(x: i64Like) -> i64:\n", - " ...\n", - "\n", - "\n", - "@fib_egraph.register\n", - "def _(f0: i64, f1: i64, x: i64):\n", - " yield set_(fib(0)).to(i64(1))\n", - " yield set_(fib(1)).to(i64(1))\n", - " yield rule(\n", - " eq(f0).to(fib(x)),\n", - " eq(f1).to(fib(x + 1)),\n", - " ).then(set_(fib(x + 2)).to(f0 + f1))\n", - "\n", - "\n", - "fib_egraph.run(7)\n", - "fib_egraph.check(eq(fib(7)).to(i64(21)))" + "data": { + "text/plain": [ + "(Num(2) * Num.var(\"x\")) + Num(6)" ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "egraph.extract(expr1)" + ] + }, + { + "cell_type": "markdown", + "id": "386bb340-06a1-4c86-88ba-33201d4214ca", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "df10f994-3e91-4663-807a-877f3dd50e04", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- `set_` and and `eq` both type safe. Required builder syntax\n" - ] + "tags": [] + }, + "source": [ + "- get back expr object\n", + "- Str representation is Python syntax\n" + ] + }, + { + "cell_type": "markdown", + "id": "f5e0d729-028a-4af4-947f-62a2e109d28a", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "5b4d8cba-3e99-4e61-afe0-c18724c0d358", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "### Include & Modules\n" - ] + "tags": [] + }, + "source": [ + "### Multipart Rules\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "0bea7d72-bf5c-47c4-95ac-e2926ad33cf3", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 11, - "id": "68179969-f9e0-43ef-851f-bd2295bd5a21", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Overwriting path.egg\n" - ] - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0_0\n", + "\n", + "\n", + "cluster_fib_0_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_0\n", + "\n", + "\n", + "cluster_fib_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "cluster_fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453\n", + "\n", + "\n", + "cluster_fib_5871781006564002453\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_4208978898528913939_0\n", + "\n", + "\n", + "cluster_fib_4208978898528913939_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_10912160959110460649\n", + "\n", + "\n", + "cluster_fib_10912160959110460649\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_10080759905092916392_0\n", + "\n", + "\n", + "cluster_fib_10080759905092916392_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "cluster_fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_17615343019692007359\n", + "\n", + "\n", + "cluster_fib_17615343019692007359\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_10912160959110460649_0\n", + "\n", + "\n", + "cluster_fib_10912160959110460649_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_4208978898528913939\n", + "\n", + "\n", + "cluster_fib_4208978898528913939\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_10080759905092916392\n", + "\n", + "\n", + "cluster_fib_10080759905092916392\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_16783941965674463102\n", + "\n", + "\n", + "cluster_fib_16783941965674463102\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "cluster_fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_16783941965674463102_0\n", + "\n", + "\n", + "cluster_fib_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_11743562013128004906\n", + "\n", + "\n", + "cluster_fib_11743562013128004906\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5040379952546458196\n", + "\n", + "\n", + "cluster_fib_5040379952546458196\n", + "\n", + "\n", + "\n", + "outer_cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "cluster_fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "fib_16783941965674463102:s->fib_16783941965674463102_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906:s->fib_11743562013128004906_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196:s->fib_5040379952546458196_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359:s->fib_17615343019692007359_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_0:s->fib_0_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_4208978898528913939:s->fib_4208978898528913939_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10080759905092916392:s->fib_10080759905092916392_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453:s->fib_5871781006564002453_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_10912160959110460649:s->fib_10912160959110460649_0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "fib_16783941965674463102\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "fib_16783941965674463102_value\n", + "\n", + "8\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_0\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "fib_16783941965674463102_0\n", + "\n", + "6\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "fib_11743562013128004906_value\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_0\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_value\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "fib_10080759905092916392_0\n", + "\n", + "8\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_0\n", + "\n", + "3\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "fib_17615343019692007359_value\n", + "\n", + "2\n", + "\n", + "\n", + "\n", + "\n", + "fib_0\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "fib_0_value\n", + "\n", + "0\n", + "\n", + "\n", + "\n", + "\n", + "fib_10912160959110460649_0\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "\n", + "fib_4208978898528913939\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "fib_4208978898528913939_value\n", + "\n", + "13\n", + "\n", + "\n", + "\n", + "\n", + "fib_10080759905092916392\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "fib_10080759905092916392_value\n", + "\n", + "21\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_0\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "fib_5040379952546458196_0\n", + "\n", + "4\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "fib_5871781006564002453_value\n", + "\n", + "1\n", + "\n", + "\n", + "\n", + "\n", + "fib_4208978898528913939_0\n", + "\n", + "7\n", + "\n", + "\n", + "\n", + "\n", + "fib_10912160959110460649\n", + "\n", + "fib\n", + "\n", + "\n", + "\n", + "\n", + "fib_10912160959110460649_value\n", + "\n", + "5\n", + "\n", + "\n", + "\n", + "\n" ], - "source": [ - "%%writefile path.egg\n", - "(relation path (i64 i64))\n", - "(relation edge (i64 i64))\n", - "\n", - "(rule ((edge x y))\n", - " ((path x y)))\n", - "\n", - "(rule ((path x y) (edge y z))\n", - " ((path x z)))" + "text/plain": [ + "" ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%egglog graph\n", + "(function fib (i64) i64)\n", + "\n", + "(set (fib 0) 0)\n", + "(set (fib 1) 1)\n", + "(rule ((= f0 (fib x))\n", + " (= f1 (fib (+ x 1))))\n", + " ((set (fib (+ x 2)) (+ f0 f1))))\n", + "\n", + "(run 7)\n", + "(check (= (fib 7) 13))" + ] + }, + { + "cell_type": "markdown", + "id": "2dc964ef-f5ee-4b7c-80a5-5a11b848ece7", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "code", - "execution_count": 12, - "id": "39273d7a-926c-4022-8514-8f5b297cfdfb", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "%%egglog\n", - "(include \"path.egg\")\n", - "(edge 1 2)\n", - "(edge 2 3)\n", - "(edge 3 4)\n", - "(run 3)\n", - "(check (path 1 3))" - ] + "tags": [] + }, + "source": [ + "- Rule that depend on facts and execute actions\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7f4bd927-ccd6-4240-aec0-123d93a782c5", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, - { - "cell_type": "markdown", - "id": "ac6aec27-654d-4cf5-bb4e-3341074ffa64", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Include another file for re-useability\n" - ] + "tags": [] + }, + "outputs": [], + "source": [ + "fib_egraph = EGraph()\n", + "\n", + "\n", + "@fib_egraph.function\n", + "def fib(x: i64Like) -> i64: ...\n", + "\n", + "\n", + "@fib_egraph.register\n", + "def _(f0: i64, f1: i64, x: i64):\n", + " yield set_(fib(0)).to(i64(1))\n", + " yield set_(fib(1)).to(i64(1))\n", + " yield rule(\n", + " eq(f0).to(fib(x)),\n", + " eq(f1).to(fib(x + 1)),\n", + " ).then(set_(fib(x + 2)).to(f0 + f1))\n", + "\n", + "\n", + "fib_egraph.run(7)\n", + "fib_egraph.check(eq(fib(7)).to(i64(21)))" + ] + }, + { + "cell_type": "markdown", + "id": "df10f994-3e91-4663-807a-877f3dd50e04", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "code", - "execution_count": 13, - "id": "ad42a38e-ad5d-476b-8ecb-a04a56a618d1", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "subslide" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "mod = Module()\n", - "path = mod.relation(\"path\", i64, i64)\n", - "edge = mod.relation(\"edge\", i64, i64)\n", - "\n", - "\n", - "@mod.register\n", - "def _(x: i64, y: i64, z: i64):\n", - " yield rule(edge(x, y)).then(path(x, y))\n", - " yield rule(path(x, y), edge(y, z)).then(path(x, z))" - ] + "tags": [] + }, + "source": [ + "- `set_` and and `eq` both type safe. Required builder syntax\n" + ] + }, + { + "cell_type": "markdown", + "id": "5b4d8cba-3e99-4e61-afe0-c18724c0d358", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" }, - { - "cell_type": "markdown", - "id": "93b04224-cf27-41aa-b3e8-4fb5f5bb1508", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Modules same in Python\n", - "- Supports defining rules, etc, but doesn't actually run them, just builds up commands\n" - ] + "tags": [] + }, + "source": [ + "### Include & Modules\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "68179969-f9e0-43ef-851f-bd2295bd5a21", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, + "tags": [] + }, + "outputs": [ { - "cell_type": "code", - "execution_count": 14, - "id": "8f8932a2-f6ea-4a7c-a4f3-41e4455aa33e", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "fragment" - }, - "tags": [] - }, - "outputs": [], - "source": [ - "egraph = EGraph([mod])\n", - "egraph.register(edge(1, 2), edge(2, 3), edge(3, 4))\n", - "egraph.run(3)\n", - "egraph.check(path(1, 3))" - ] + "name": "stdout", + "output_type": "stream", + "text": [ + "Overwriting path.egg\n" + ] + } + ], + "source": [ + "%%writefile path.egg\n", + "(relation path (i64 i64))\n", + "(relation edge (i64 i64))\n", + "\n", + "(rule ((edge x y))\n", + " ((path x y)))\n", + "\n", + "(rule ((path x y) (edge y z))\n", + " ((path x z)))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "39273d7a-926c-4022-8514-8f5b297cfdfb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - { - "cell_type": "markdown", - "id": "99f0f9f2-297d-45ac-bc84-053f591d894d", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "notes" - }, - "tags": [] - }, - "source": [ - "- Then when we depend on them, it will run those commands first.\n", - "- Allows distribution of code and others to re-use it, using existing Python import mechanisms.\n" - ] + "tags": [] + }, + "outputs": [], + "source": [ + "%%egglog\n", + "(include \"path.egg\")\n", + "(edge 1 2)\n", + "(edge 2 3)\n", + "(edge 3 4)\n", + "(run 3)\n", + "(check (path 1 3))" + ] + }, + { + "cell_type": "markdown", + "id": "ac6aec27-654d-4cf5-bb4e-3341074ffa64", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - { - "cell_type": "markdown", - "id": "52e042f3-adc3-466c-bea0-0a00cd037377", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Possible next steps?\n", - "\n", - "- Try getting toehold in existing library (like Ibis) to see if constrained egglog approach can still be useful.\n", - " - Add support for Python objects as builtin sort.\n", - "- Upstream egglog improvements which could help with reuse\n", - " - First class functions (would help with implementing things like reductions, mapping)\n", - " - User defined generic sorts (i.e. an array type agnostic to inner values)\n" - ] + "tags": [] + }, + "source": [ + "- Include another file for re-useability\n" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "ad42a38e-ad5d-476b-8ecb-a04a56a618d1", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "subslide" }, - { - "cell_type": "markdown", - "id": "2b67e0b8-3c8d-45a5-a041-4293da7aed9e", - "metadata": { - "editable": true, - "slideshow": { - "slide_type": "slide" - }, - "tags": [] - }, - "source": [ - "## Thank you!\n", - "\n", - "```bash\n", - "pip install egglog\n", - "```\n", - "\n", - "```python\n", - "from egglog import *\n", - "\n", - "egraph = EGraph()\n", - "...\n", - "```\n", - "\n", - "_Come say hello at [github.com/egraphs-good/egglog-python](https://github.com/egraphs-good/egglog-python)!_\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" + "tags": [] + }, + "outputs": [], + "source": [ + "mod = Module()\n", + "path = mod.relation(\"path\", i64, i64)\n", + "edge = mod.relation(\"edge\", i64, i64)\n", + "\n", + "\n", + "@mod.register\n", + "def _(x: i64, y: i64, z: i64):\n", + " yield rule(edge(x, y)).then(path(x, y))\n", + " yield rule(path(x, y), edge(y, z)).then(path(x, z))" + ] + }, + { + "cell_type": "markdown", + "id": "93b04224-cf27-41aa-b3e8-4fb5f5bb1508", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" }, - "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.10.9" + "tags": [] + }, + "source": [ + "- Modules same in Python\n", + "- Supports defining rules, etc, but doesn't actually run them, just builds up commands\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "8f8932a2-f6ea-4a7c-a4f3-41e4455aa33e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "fragment" }, - "mystnb": { - "execution_mode": "off" - } + "tags": [] + }, + "outputs": [], + "source": [ + "egraph = EGraph([mod])\n", + "egraph.register(edge(1, 2), edge(2, 3), edge(3, 4))\n", + "egraph.run(3)\n", + "egraph.check(path(1, 3))" + ] + }, + { + "cell_type": "markdown", + "id": "99f0f9f2-297d-45ac-bc84-053f591d894d", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "notes" + }, + "tags": [] + }, + "source": [ + "- Then when we depend on them, it will run those commands first.\n", + "- Allows distribution of code and others to re-use it, using existing Python import mechanisms.\n" + ] + }, + { + "cell_type": "markdown", + "id": "52e042f3-adc3-466c-bea0-0a00cd037377", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## Possible next steps?\n", + "\n", + "- Try getting toehold in existing library (like Ibis) to see if constrained egglog approach can still be useful.\n", + " - Add support for Python objects as builtin sort.\n", + "- Upstream egglog improvements which could help with reuse\n", + " - First class functions (would help with implementing things like reductions, mapping)\n", + " - User defined generic sorts (i.e. an array type agnostic to inner values)\n" + ] + }, + { + "cell_type": "markdown", + "id": "2b67e0b8-3c8d-45a5-a041-4293da7aed9e", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "slide" + }, + "tags": [] + }, + "source": [ + "## Thank you!\n", + "\n", + "```bash\n", + "pip install egglog\n", + "```\n", + "\n", + "```python\n", + "from egglog import *\n", + "\n", + "egraph = EGraph()\n", + "...\n", + "```\n", + "\n", + "_Come say hello at [github.com/egraphs-good/egglog-python](https://github.com/egraphs-good/egglog-python)!_\n" + ] + } + ], + "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.10.9" }, - "nbformat": 4, - "nbformat_minor": 5 + "mystnb": { + "execution_mode": "off" + } + }, + "nbformat": 4, + "nbformat_minor": 5 } diff --git a/docs/tutorials/getting-started.ipynb b/docs/tutorials/getting-started.ipynb index 95396b89..0644eae4 100644 --- a/docs/tutorials/getting-started.ipynb +++ b/docs/tutorials/getting-started.ipynb @@ -92,15 +92,12 @@ " Dim(3) * Dim.named(\"n\")\n", " \"\"\"\n", "\n", - " def __init__(self, value: i64Like) -> None:\n", - " ...\n", + " def __init__(self, value: i64Like) -> None: ...\n", "\n", " @classmethod\n", - " def named(cls, name: StringLike) -> Dim:\n", - " ...\n", + " def named(cls, name: StringLike) -> Dim: ...\n", "\n", - " def __mul__(self, other: Dim) -> Dim:\n", - " ..." + " def __mul__(self, other: Dim) -> Dim: ..." ] }, { @@ -439,32 +436,27 @@ " \"\"\"\n", " Create an identity matrix of the given dimension.\n", " \"\"\"\n", - " ...\n", "\n", " @classmethod\n", " def named(cls, name: StringLike) -> Matrix:\n", " \"\"\"\n", " Create a named matrix.\n", " \"\"\"\n", - " ...\n", "\n", " def __matmul__(self, other: Matrix) -> Matrix:\n", " \"\"\"\n", " Matrix multiplication.\n", " \"\"\"\n", - " ...\n", "\n", " def nrows(self) -> Dim:\n", " \"\"\"\n", " Number of rows in the matrix.\n", " \"\"\"\n", - " ...\n", "\n", " def ncols(self) -> Dim:\n", " \"\"\"\n", " Number of columns in the matrix.\n", " \"\"\"\n", - " ...\n", "\n", "\n", "@egraph.function\n", @@ -473,8 +465,7 @@ " Kronecker product of two matrices.\n", "\n", " https://en.wikipedia.org/wiki/Kronecker_product#Definition\n", - " \"\"\"\n", - " ..." + " \"\"\"" ] }, { diff --git a/docs/tutorials/sklearn.ipynb b/docs/tutorials/sklearn.ipynb index e7a3307e..80ed37f1 100644 --- a/docs/tutorials/sklearn.ipynb +++ b/docs/tutorials/sklearn.ipynb @@ -1,6639 +1,6640 @@ { - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "```{post} 2023-10-26\n", - "\n", - "```\n" - ] - }, - { - "cell_type": "markdown", - "id": "34e1966a", - "metadata": {}, - "source": [ - "# Optimizing Scikit-Learn with Array API and Numba\n", - "\n", - "In this tutorial, we will walk through increasing the performance of your scikit-learn code using `egglog` and [`numba`](https://numba.readthedocs.io/en/stable/user/5minguide.html).\n", - "\n", - "One of the goals of `egglog` is to be used by other scientific computing libraries to create flexible APIs,\n", - "which conform to existing user expectations but allow a greater flexability in how they perform execution.\n", - "\n", - "To work towards that we goal, we have built an prototype of a [Array API standard](https://data-apis.org/array-api/2022.12/index.html) conformant API\n", - "that can be used with [Scikit-Learn's experimental Array API support](https://scikit-learn.org/stable/modules/array_api.html),\n", - "to optimize it using Numba.\n", - "\n", - "## Normal execution\n", - "\n", - "We can create a test data set and use `LDA` to create a classification. Then we can run it on the dataset, to\n", - "return the estimated classification for out test data:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "6b130384", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "array([[ 0.64233002],\n", - " [ 0.63661245],\n", - " [-1.603293 ],\n", - " ...,\n", - " [-1.1506433 ],\n", - " [ 0.71687176],\n", - " [-1.51119579]])" - ] - }, - "execution_count": 1, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from sklearn import config_context\n", - "from sklearn.datasets import make_classification\n", - "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n", - "\n", - "\n", - "def run_lda(x, y):\n", - " with config_context(array_api_dispatch=True):\n", - " lda = LinearDiscriminantAnalysis()\n", - " return lda.fit(x, y).transform(x)\n", - "\n", - "\n", - "X_np, y_np = make_classification(random_state=0, n_samples=1000000)\n", - "run_lda(X_np, y_np)" - ] - }, - { - "cell_type": "markdown", - "id": "df1da938", - "metadata": {}, - "source": [ - "## Building our inputs\n", - "\n", - "Now, we can try executing it with `egglog` instead. In this mode, we aren't actually passing in any particular\n", - "NDArray, but instead just using variables to represent the X and Y values.\n", - "\n", - "These are defined in the [`egglog.exp.array_api` module](https://github.com/egraphs-good/egglog-python/blob/main/python/egglog/exp/array_api.py), as typed values:\n", - "\n", - "```python\n", - "@array_api_module.class_\n", - "class NDArray(Expr):\n", - " @array_api_module.method(cost=200)\n", - " @classmethod\n", - " def var(cls, name: StringLike) -> NDArray: ...\n", - "\n", - " @property\n", - " def shape(self) -> TupleInt: ...\n", - "\n", - " ...\n", - "\n", - "@array_api_module.function(mutates_first_arg=True)\n", - "def assume_shape(x: NDArray, shape: TupleInt) -> None: ...\n", - "```\n", - "\n", - "We can use these functon to provides some metadata about the arguments as well:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "1c216ca4", - "metadata": {}, - "outputs": [], - "source": [ - "from copy import copy\n", - "\n", - "from egglog.exp.array_api import (\n", - " NDArray,\n", - " assume_dtype,\n", - " assume_shape,\n", - " assume_isfinite,\n", - " assume_value_one_of,\n", - ")\n", - "\n", - "X_arr = NDArray.var(\"X\")\n", - "X_orig = copy(X_arr)\n", - "\n", - "assume_dtype(X_arr, X_np.dtype)\n", - "assume_shape(X_arr, X_np.shape)\n", - "assume_isfinite(X_arr)\n", - "\n", - "y_arr = NDArray.var(\"y\")\n", - "y_orig = copy(y_arr)\n", - "\n", - "assume_dtype(y_arr, y_np.dtype)\n", - "assume_shape(y_arr, y_np.shape)\n", - "assume_value_one_of(y_arr, (0, 1))" - ] - }, + "cells": [ + { + "cell_type": "markdown", + "id": "7fb27b941602401d91542211134fc71a", + "metadata": {}, + "source": [ + "```{post} 2023-10-26\n", + "\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "34e1966a", + "metadata": {}, + "source": [ + "# Optimizing Scikit-Learn with Array API and Numba\n", + "\n", + "In this tutorial, we will walk through increasing the performance of your scikit-learn code using `egglog` and [`numba`](https://numba.readthedocs.io/en/stable/user/5minguide.html).\n", + "\n", + "One of the goals of `egglog` is to be used by other scientific computing libraries to create flexible APIs,\n", + "which conform to existing user expectations but allow a greater flexability in how they perform execution.\n", + "\n", + "To work towards that we goal, we have built an prototype of a [Array API standard](https://data-apis.org/array-api/2022.12/index.html) conformant API\n", + "that can be used with [Scikit-Learn's experimental Array API support](https://scikit-learn.org/stable/modules/array_api.html),\n", + "to optimize it using Numba.\n", + "\n", + "## Normal execution\n", + "\n", + "We can create a test data set and use `LDA` to create a classification. Then we can run it on the dataset, to\n", + "return the estimated classification for out test data:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "6b130384", + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "id": "a184f6e6", - "metadata": {}, - "source": [ - "While most of the execution can be deferred, every time sklearn triggers Python control flow (`if`, `for`, etc), we\n", - "need to execute eagerly and be able to give a definate value. For example, scikit-learn checks to makes sure that the\n", - "number of samples we pass in is greater than the number of unique classes:\n", - "\n", - "```python\n", - "class LinearDiscriminantAnalysis(...):\n", - " ...\n", - " def fit(self, X, y):\n", - " ...\n", - " self.classes_ = unique_labels(y)\n", - " n_samples, _ = X.shape\n", - " n_classes = self.classes_.shape[0]\n", - "\n", - " if n_samples == n_classes:\n", - " raise ValueError(\n", - " \"The number of samples must be more than the number of classes.\"\n", - " )\n", - " ...\n", - "```\n", - "\n", - "Without the assumptions above, we wouldn't know if the conditional is true or false. So we provide just enough information\n", - "for sklearn to finish executing and give us a result.\n", - "\n", - "## Getting a result\n", - "\n", - "We can now run our lda function with our inputs, which have the constraints about them saved, and see the graph which\n", - "will show all of the intermerdiate results we had to compute to get our answer:\n" + "data": { + "text/plain": [ + "array([[ 0.64233002],\n", + " [ 0.63661245],\n", + " [-1.603293 ],\n", + " ...,\n", + " [-1.1506433 ],\n", + " [ 0.71687176],\n", + " [-1.51119579]])" ] - }, + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "from sklearn import config_context\n", + "from sklearn.datasets import make_classification\n", + "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n", + "\n", + "\n", + "def run_lda(x, y):\n", + " with config_context(array_api_dispatch=True):\n", + " lda = LinearDiscriminantAnalysis()\n", + " return lda.fit(x, y).transform(x)\n", + "\n", + "\n", + "X_np, y_np = make_classification(random_state=0, n_samples=1000000)\n", + "run_lda(X_np, y_np)" + ] + }, + { + "cell_type": "markdown", + "id": "df1da938", + "metadata": {}, + "source": [ + "## Building our inputs\n", + "\n", + "Now, we can try executing it with `egglog` instead. In this mode, we aren't actually passing in any particular\n", + "NDArray, but instead just using variables to represent the X and Y values.\n", + "\n", + "These are defined in the [`egglog.exp.array_api` module](https://github.com/egraphs-good/egglog-python/blob/main/python/egglog/exp/array_api.py), as typed values:\n", + "\n", + "```python\n", + "@array_api_module.class_\n", + "class NDArray(Expr):\n", + " @array_api_module.method(cost=200)\n", + " @classmethod\n", + " def var(cls, name: StringLike) -> NDArray: ...\n", + "\n", + " @property\n", + " def shape(self) -> TupleInt: ...\n", + "\n", + " ...\n", + "\n", + "@array_api_module.function(mutates_first_arg=True)\n", + "def assume_shape(x: NDArray, shape: TupleInt) -> None: ...\n", + "```\n", + "\n", + "We can use these functon to provides some metadata about the arguments as well:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1c216ca4", + "metadata": {}, + "outputs": [], + "source": [ + "from copy import copy\n", + "\n", + "from egglog.exp.array_api import (\n", + " NDArray,\n", + " assume_dtype,\n", + " assume_isfinite,\n", + " assume_shape,\n", + " assume_value_one_of,\n", + ")\n", + "\n", + "X_arr = NDArray.var(\"X\")\n", + "X_orig = copy(X_arr)\n", + "\n", + "assume_dtype(X_arr, X_np.dtype)\n", + "assume_shape(X_arr, X_np.shape)\n", + "assume_isfinite(X_arr)\n", + "\n", + "y_arr = NDArray.var(\"y\")\n", + "y_orig = copy(y_arr)\n", + "\n", + "assume_dtype(y_arr, y_np.dtype)\n", + "assume_shape(y_arr, y_np.shape)\n", + "assume_value_one_of(y_arr, (0, 1))" + ] + }, + { + "cell_type": "markdown", + "id": "a184f6e6", + "metadata": {}, + "source": [ + "While most of the execution can be deferred, every time sklearn triggers Python control flow (`if`, `for`, etc), we\n", + "need to execute eagerly and be able to give a definate value. For example, scikit-learn checks to makes sure that the\n", + "number of samples we pass in is greater than the number of unique classes:\n", + "\n", + "```python\n", + "class LinearDiscriminantAnalysis(...):\n", + " ...\n", + " def fit(self, X, y):\n", + " ...\n", + " self.classes_ = unique_labels(y)\n", + " n_samples, _ = X.shape\n", + " n_classes = self.classes_.shape[0]\n", + "\n", + " if n_samples == n_classes:\n", + " raise ValueError(\n", + " \"The number of samples must be more than the number of classes.\"\n", + " )\n", + " ...\n", + "```\n", + "\n", + "Without the assumptions above, we wouldn't know if the conditional is true or false. So we provide just enough information\n", + "for sklearn to finish executing and give us a result.\n", + "\n", + "## Getting a result\n", + "\n", + "We can now run our lda function with our inputs, which have the constraints about them saved, and see the graph which\n", + "will show all of the intermerdiate results we had to compute to get our answer:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3d7291d8", + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 3, - "id": "3d7291d8", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "
_NDArray_1 = NDArray.var("X")\n",
-              "assume_dtype(_NDArray_1, DType.float64)\n",
-              "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n",
-              "assume_isfinite(_NDArray_1)\n",
-              "_NDArray_2 = NDArray.var("y")\n",
-              "assume_dtype(_NDArray_2, DType.int64)\n",
-              "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n",
-              "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n",
-              "_NDArray_3 = asarray(reshape(asarray(_NDArray_2), TupleInt(Int(-1))))\n",
-              "_NDArray_4 = astype(unique_counts(_NDArray_3)[Int(1)], asarray(_NDArray_1).dtype) / NDArray.scalar(Value.float(Float(1000000.0)))\n",
-              "_NDArray_5 = zeros(\n",
-              "    TupleInt(unique_inverse(_NDArray_3)[Int(0)].shape[Int(0)]) + TupleInt(asarray(_NDArray_1).shape[Int(1)]),\n",
-              "    OptionalDType.some(asarray(_NDArray_1).dtype),\n",
-              "    OptionalDevice.some(asarray(_NDArray_1).device),\n",
-              ")\n",
-              "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n",
-              "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n",
-              "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n",
-              "_NDArray_5[_IndexKey_1] = mean(asarray(_NDArray_1)[ndarray_index(unique_inverse(_NDArray_3)[Int(1)] == NDArray.scalar(Value.int(Int(0))))], _OptionalIntOrTuple_1)\n",
-              "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n",
-              "_NDArray_5[_IndexKey_2] = mean(asarray(_NDArray_1)[ndarray_index(unique_inverse(_NDArray_3)[Int(1)] == NDArray.scalar(Value.int(Int(1))))], _OptionalIntOrTuple_1)\n",
-              "_NDArray_6 = unique_values(concat(TupleNDArray(unique_values(asarray(_NDArray_3)))))\n",
-              "_NDArray_7 = concat(\n",
-              "    TupleNDArray(asarray(_NDArray_1)[ndarray_index(_NDArray_3 == _NDArray_6[IndexKey.int(Int(0))])] - _NDArray_5[_IndexKey_1])\n",
-              "    + TupleNDArray(asarray(_NDArray_1)[ndarray_index(_NDArray_3 == _NDArray_6[IndexKey.int(Int(1))])] - _NDArray_5[_IndexKey_2]),\n",
-              "    OptionalInt.some(Int(0)),\n",
-              ")\n",
-              "_NDArray_8 = std(_NDArray_7, _OptionalIntOrTuple_1)\n",
-              "_NDArray_8[ndarray_index(std(_NDArray_7, _OptionalIntOrTuple_1) == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n",
-              "_TupleNDArray_1 = svd(\n",
-              "    sqrt(asarray(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(asarray(_NDArray_1).shape[Int(0)] - _NDArray_6.shape[Int(0)]))))) * (_NDArray_7 / _NDArray_8), FALSE\n",
-              ")\n",
-              "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n",
-              "_NDArray_9 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_8).T / _TupleNDArray_1[\n",
-              "    Int(1)\n",
-              "][IndexKey.slice(_Slice_1)]\n",
-              "_TupleNDArray_2 = svd(\n",
-              "    (\n",
-              "        sqrt(\n",
-              "            (NDArray.scalar(Value.int(asarray(_NDArray_1).shape[Int(0)])) * _NDArray_4)\n",
-              "            * NDArray.scalar(Value.float(Float(1.0) / Float.from_int(_NDArray_6.shape[Int(0)] - Int(1))))\n",
-              "        )\n",
-              "        * (_NDArray_5 - (_NDArray_4 @ _NDArray_5)).T\n",
-              "    ).T\n",
-              "    @ _NDArray_9,\n",
-              "    FALSE,\n",
-              ")\n",
-              "(\n",
-              "    (asarray(_NDArray_1) - (_NDArray_4 @ _NDArray_5))\n",
-              "    @ (\n",
-              "        _NDArray_9\n",
-              "        @ _TupleNDArray_2[Int(2)].T[\n",
-              "            IndexKey.multi_axis(\n",
-              "                _MultiAxisIndexKey_1\n",
-              "                + MultiAxisIndexKey(\n",
-              "                    MultiAxisIndexKeyItem.slice(\n",
-              "                        Slice(\n",
-              "                            OptionalInt.none,\n",
-              "                            OptionalInt.some(\n",
-              "                                sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n",
-              "                                .to_value()\n",
-              "                                .to_int\n",
-              "                            ),\n",
-              "                        )\n",
-              "                    )\n",
-              "                )\n",
-              "            )\n",
-              "        ]\n",
-              "    )\n",
-              ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(_NDArray_6.shape[Int(0)] - Int(1))))))]\n",
-              "
\n" - ], - "text/latex": [ - "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{X}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}isfinite}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{y}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int64}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}value\\PYZus{}one\\PYZus{}of}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{=} \\PY{n}{asarray}\\PY{p}{(}\\PY{n}{reshape}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{)}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{=} \\PY{n}{astype}\\PY{p}{(}\\PY{n}{unique\\PYZus{}counts}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{dtype}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1000000.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{=} \\PY{n}{zeros}\\PY{p}{(}\n", - " \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,}\n", - " \\PY{n}{OptionalDType}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{dtype}\\PY{p}{)}\\PY{p}{,}\n", - " \\PY{n}{OptionalDevice}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{device}\\PY{p}{)}\\PY{p}{,}\n", - "\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1} \\PY{o}{=} \\PY{n}{OptionalIntOrTuple}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{IntOrTuple}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]} \\PY{o}{=} \\PY{n}{mean}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]} \\PY{o}{=} \\PY{n}{mean}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}6} \\PY{o}{=} \\PY{n}{unique\\PYZus{}values}\\PY{p}{(}\\PY{n}{concat}\\PY{p}{(}\\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{unique\\PYZus{}values}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{=} \\PY{n}{concat}\\PY{p}{(}\n", - " \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{==} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]}\\PY{p}{)}\n", - " \\PY{o}{+} \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{==} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,}\n", - " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,}\n", - "\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}8} \\PY{o}{=} \\PY{n}{std}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{std}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\n", - " \\PY{n}{sqrt}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)} \\PY{o}{/} \\PY{n}{Float}\\PY{o}{.}\\PY{n}{from\\PYZus{}int}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{p}{)}\\PY{p}{,} \\PY{n}{FALSE}\n", - "\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}Slice\\PYZus{}1} \\PY{o}{=} \\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}int}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}9} \\PY{o}{=} \\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{/} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\n", - " \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\n", - "\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{]}\n", - "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\n", - " \\PY{p}{(}\n", - " \\PY{n}{sqrt}\\PY{p}{(}\n", - " \\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\n", - " \\PY{o}{*} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)} \\PY{o}{/} \\PY{n}{Float}\\PY{o}{.}\\PY{n}{from\\PYZus{}int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T}\n", - " \\PY{p}{)}\\PY{o}{.}\\PY{n}{T}\n", - " \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}9}\\PY{p}{,}\n", - " \\PY{n}{FALSE}\\PY{p}{,}\n", - "\\PY{p}{)}\n", - "\\PY{p}{(}\n", - " \\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{)}\\PY{p}{)}\n", - " \\PY{o}{@} \\PY{p}{(}\n", - " \\PY{n}{\\PYZus{}NDArray\\PYZus{}9}\n", - " \\PY{o}{@} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{o}{.}\\PY{n}{T}\\PY{p}{[}\n", - " \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\n", - " \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\n", - " \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\n", - " \\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\n", - " \\PY{n}{Slice}\\PY{p}{(}\n", - " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,}\n", - " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\n", - " \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\n", - " \\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\n", - " \\PY{o}{.}\\PY{n}{to\\PYZus{}int}\n", - " \\PY{p}{)}\\PY{p}{,}\n", - " \\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{p}{]}\n", - " \\PY{p}{)}\n", - "\\PY{p}{)}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", - "\\end{Verbatim}\n" - ], - "text/plain": [ - "_NDArray_1 = NDArray.var(\"X\")\n", - "assume_dtype(_NDArray_1, DType.float64)\n", - "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n", - "assume_isfinite(_NDArray_1)\n", - "_NDArray_2 = NDArray.var(\"y\")\n", - "assume_dtype(_NDArray_2, DType.int64)\n", - "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n", - "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n", - "_NDArray_3 = asarray(reshape(asarray(_NDArray_2), TupleInt(Int(-1))))\n", - "_NDArray_4 = astype(unique_counts(_NDArray_3)[Int(1)], asarray(_NDArray_1).dtype) / NDArray.scalar(Value.float(Float(1000000.0)))\n", - "_NDArray_5 = zeros(\n", - " TupleInt(unique_inverse(_NDArray_3)[Int(0)].shape[Int(0)]) + TupleInt(asarray(_NDArray_1).shape[Int(1)]),\n", - " OptionalDType.some(asarray(_NDArray_1).dtype),\n", - " OptionalDevice.some(asarray(_NDArray_1).device),\n", - ")\n", - "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n", - "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n", - "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n", - "_NDArray_5[_IndexKey_1] = mean(asarray(_NDArray_1)[ndarray_index(unique_inverse(_NDArray_3)[Int(1)] == NDArray.scalar(Value.int(Int(0))))], _OptionalIntOrTuple_1)\n", - "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n", - "_NDArray_5[_IndexKey_2] = mean(asarray(_NDArray_1)[ndarray_index(unique_inverse(_NDArray_3)[Int(1)] == NDArray.scalar(Value.int(Int(1))))], _OptionalIntOrTuple_1)\n", - "_NDArray_6 = unique_values(concat(TupleNDArray(unique_values(asarray(_NDArray_3)))))\n", - "_NDArray_7 = concat(\n", - " TupleNDArray(asarray(_NDArray_1)[ndarray_index(_NDArray_3 == _NDArray_6[IndexKey.int(Int(0))])] - _NDArray_5[_IndexKey_1])\n", - " + TupleNDArray(asarray(_NDArray_1)[ndarray_index(_NDArray_3 == _NDArray_6[IndexKey.int(Int(1))])] - _NDArray_5[_IndexKey_2]),\n", - " OptionalInt.some(Int(0)),\n", - ")\n", - "_NDArray_8 = std(_NDArray_7, _OptionalIntOrTuple_1)\n", - "_NDArray_8[ndarray_index(std(_NDArray_7, _OptionalIntOrTuple_1) == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n", - "_TupleNDArray_1 = svd(\n", - " sqrt(asarray(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(asarray(_NDArray_1).shape[Int(0)] - _NDArray_6.shape[Int(0)]))))) * (_NDArray_7 / _NDArray_8), FALSE\n", - ")\n", - "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n", - "_NDArray_9 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_8).T / _TupleNDArray_1[\n", - " Int(1)\n", - "][IndexKey.slice(_Slice_1)]\n", - "_TupleNDArray_2 = svd(\n", - " (\n", - " sqrt(\n", - " (NDArray.scalar(Value.int(asarray(_NDArray_1).shape[Int(0)])) * _NDArray_4)\n", - " * NDArray.scalar(Value.float(Float(1.0) / Float.from_int(_NDArray_6.shape[Int(0)] - Int(1))))\n", - " )\n", - " * (_NDArray_5 - (_NDArray_4 @ _NDArray_5)).T\n", - " ).T\n", - " @ _NDArray_9,\n", - " FALSE,\n", - ")\n", - "(\n", - " (asarray(_NDArray_1) - (_NDArray_4 @ _NDArray_5))\n", - " @ (\n", - " _NDArray_9\n", - " @ _TupleNDArray_2[Int(2)].T[\n", - " IndexKey.multi_axis(\n", - " _MultiAxisIndexKey_1\n", - " + MultiAxisIndexKey(\n", - " MultiAxisIndexKeyItem.slice(\n", - " Slice(\n", - " OptionalInt.none,\n", - " OptionalInt.some(\n", - " sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n", - " .to_value()\n", - " .to_int\n", - " ),\n", - " )\n", - " )\n", - " )\n", - " )\n", - " ]\n", - " )\n", - ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(_NDArray_6.shape[Int(0)] - Int(1))))))]" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "" ], - "source": [ - "from egglog import EGraph\n", - "from egglog.exp.array_api import array_api_module\n", - "\n", - "with EGraph([array_api_module]) as egraph:\n", - " X_r2 = run_lda(X_arr, y_arr)\n", - " egraph.display(n_inline_leaves=3, split_primitive_outputs=True)\n", - "X_r2" + "text/plain": [ + "" ] + }, + "metadata": {}, + "output_type": "display_data" }, { - "cell_type": "markdown", - "id": "580da17b", - "metadata": {}, - "source": [ - "We now have extracted out a program which is semantically equivalent to the original call! One thing you might notice\n", - "is that the expression has more types than customary NumPy code. Every object is lifted into a strongly typed `egglog`\n", - "class. This is so that when we run optimizations, we know the types of all the objects. It still is compatible with\n", - "normal Python objects, but they are [converted](type-promotion) when they are passed as argument.\n", - "\n", - "## Optimizing our result\n", - "\n", - "Now that we have the an expression, we can run our rewrite rules to \"optimize\" it, extracting out the lowest cost\n", - "(smallest) expression afterword:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "4d3cd4f3", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
_NDArray_1 = NDArray.var("X")\n",
-              "assume_dtype(_NDArray_1, DType.float64)\n",
-              "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n",
-              "assume_isfinite(_NDArray_1)\n",
-              "_NDArray_2 = NDArray.var("y")\n",
-              "assume_dtype(_NDArray_2, DType.int64)\n",
-              "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n",
-              "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n",
-              "_NDArray_3 = astype(unique_counts(_NDArray_2)[Int(1)], DType.float64) / NDArray.scalar(Value.float(Float(1000000.0)))\n",
-              "_NDArray_4 = zeros(TupleInt(Int(2)) + TupleInt(Int(20)), OptionalDType.some(DType.float64), OptionalDevice.some(_NDArray_1.device))\n",
-              "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n",
-              "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n",
-              "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n",
-              "_NDArray_4[_IndexKey_1] = mean(_NDArray_1[ndarray_index(unique_inverse(_NDArray_2)[Int(1)] == NDArray.scalar(Value.int(Int(0))))], _OptionalIntOrTuple_1)\n",
-              "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n",
-              "_NDArray_4[_IndexKey_2] = mean(_NDArray_1[ndarray_index(unique_inverse(_NDArray_2)[Int(1)] == NDArray.scalar(Value.int(Int(1))))], _OptionalIntOrTuple_1)\n",
-              "_NDArray_5 = concat(\n",
-              "    TupleNDArray(_NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(0))))] - _NDArray_4[_IndexKey_1])\n",
-              "    + TupleNDArray(_NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(1))))] - _NDArray_4[_IndexKey_2]),\n",
-              "    OptionalInt.some(Int(0)),\n",
-              ")\n",
-              "_NDArray_6 = std(_NDArray_5, _OptionalIntOrTuple_1)\n",
-              "_NDArray_6[ndarray_index(std(_NDArray_5, _OptionalIntOrTuple_1) == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n",
-              "_TupleNDArray_1 = svd(sqrt(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(Int(999998))))) * (_NDArray_5 / _NDArray_6), FALSE)\n",
-              "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n",
-              "_NDArray_7 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_6).T / _TupleNDArray_1[\n",
-              "    Int(1)\n",
-              "][IndexKey.slice(_Slice_1)]\n",
-              "_TupleNDArray_2 = svd(\n",
-              "    (sqrt((NDArray.scalar(Value.int(Int(1000000))) * _NDArray_3) * NDArray.scalar(Value.float(Float(1.0)))) * (_NDArray_4 - (_NDArray_3 @ _NDArray_4)).T).T @ _NDArray_7, FALSE\n",
-              ")\n",
-              "(\n",
-              "    (_NDArray_1 - (_NDArray_3 @ _NDArray_4))\n",
-              "    @ (\n",
-              "        _NDArray_7\n",
-              "        @ _TupleNDArray_2[Int(2)].T[\n",
-              "            IndexKey.multi_axis(\n",
-              "                _MultiAxisIndexKey_1\n",
-              "                + MultiAxisIndexKey(\n",
-              "                    MultiAxisIndexKeyItem.slice(\n",
-              "                        Slice(\n",
-              "                            OptionalInt.none,\n",
-              "                            OptionalInt.some(\n",
-              "                                sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n",
-              "                                .to_value()\n",
-              "                                .to_int\n",
-              "                            ),\n",
-              "                        )\n",
-              "                    )\n",
-              "                )\n",
-              "            )\n",
-              "        ]\n",
-              "    )\n",
-              ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(Int(1))))))]\n",
-              "
\n" - ], - "text/latex": [ - "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{X}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}isfinite}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{y}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int64}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}value\\PYZus{}one\\PYZus{}of}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{=} \\PY{n}{astype}\\PY{p}{(}\\PY{n}{unique\\PYZus{}counts}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1000000.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{=} \\PY{n}{zeros}\\PY{p}{(}\\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalDType}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalDevice}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{o}{.}\\PY{n}{device}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1} \\PY{o}{=} \\PY{n}{OptionalIntOrTuple}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{IntOrTuple}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]} \\PY{o}{=} \\PY{n}{mean}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]} \\PY{o}{=} \\PY{n}{mean}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{=} \\PY{n}{concat}\\PY{p}{(}\n", - " \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]}\\PY{p}{)}\n", - " \\PY{o}{+} \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,}\n", - " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,}\n", - "\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}6} \\PY{o}{=} \\PY{n}{std}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{std}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\\PY{n}{sqrt}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)} \\PY{o}{/} \\PY{n}{Float}\\PY{o}{.}\\PY{n}{from\\PYZus{}int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{999998}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{)}\\PY{p}{,} \\PY{n}{FALSE}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}Slice\\PYZus{}1} \\PY{o}{=} \\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}int}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{=} \\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{/} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\n", - " \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\n", - "\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{]}\n", - "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\n", - " \\PY{p}{(}\\PY{n}{sqrt}\\PY{p}{(}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)} \\PY{o}{*} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{p}{,} \\PY{n}{FALSE}\n", - "\\PY{p}{)}\n", - "\\PY{p}{(}\n", - " \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\\PY{p}{)}\n", - " \\PY{o}{@} \\PY{p}{(}\n", - " \\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\n", - " \\PY{o}{@} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{o}{.}\\PY{n}{T}\\PY{p}{[}\n", - " \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\n", - " \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\n", - " \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\n", - " \\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\n", - " \\PY{n}{Slice}\\PY{p}{(}\n", - " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,}\n", - " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\n", - " \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\n", - " \\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\n", - " \\PY{o}{.}\\PY{n}{to\\PYZus{}int}\n", - " \\PY{p}{)}\\PY{p}{,}\n", - " \\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{p}{]}\n", - " \\PY{p}{)}\n", - "\\PY{p}{)}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", - "\\end{Verbatim}\n" - ], - "text/plain": [ - "_NDArray_1 = NDArray.var(\"X\")\n", - "assume_dtype(_NDArray_1, DType.float64)\n", - "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n", - "assume_isfinite(_NDArray_1)\n", - "_NDArray_2 = NDArray.var(\"y\")\n", - "assume_dtype(_NDArray_2, DType.int64)\n", - "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n", - "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n", - "_NDArray_3 = astype(unique_counts(_NDArray_2)[Int(1)], DType.float64) / NDArray.scalar(Value.float(Float(1000000.0)))\n", - "_NDArray_4 = zeros(TupleInt(Int(2)) + TupleInt(Int(20)), OptionalDType.some(DType.float64), OptionalDevice.some(_NDArray_1.device))\n", - "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n", - "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n", - "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n", - "_NDArray_4[_IndexKey_1] = mean(_NDArray_1[ndarray_index(unique_inverse(_NDArray_2)[Int(1)] == NDArray.scalar(Value.int(Int(0))))], _OptionalIntOrTuple_1)\n", - "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n", - "_NDArray_4[_IndexKey_2] = mean(_NDArray_1[ndarray_index(unique_inverse(_NDArray_2)[Int(1)] == NDArray.scalar(Value.int(Int(1))))], _OptionalIntOrTuple_1)\n", - "_NDArray_5 = concat(\n", - " TupleNDArray(_NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(0))))] - _NDArray_4[_IndexKey_1])\n", - " + TupleNDArray(_NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(1))))] - _NDArray_4[_IndexKey_2]),\n", - " OptionalInt.some(Int(0)),\n", - ")\n", - "_NDArray_6 = std(_NDArray_5, _OptionalIntOrTuple_1)\n", - "_NDArray_6[ndarray_index(std(_NDArray_5, _OptionalIntOrTuple_1) == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n", - "_TupleNDArray_1 = svd(sqrt(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(Int(999998))))) * (_NDArray_5 / _NDArray_6), FALSE)\n", - "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n", - "_NDArray_7 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_6).T / _TupleNDArray_1[\n", - " Int(1)\n", - "][IndexKey.slice(_Slice_1)]\n", - "_TupleNDArray_2 = svd(\n", - " (sqrt((NDArray.scalar(Value.int(Int(1000000))) * _NDArray_3) * NDArray.scalar(Value.float(Float(1.0)))) * (_NDArray_4 - (_NDArray_3 @ _NDArray_4)).T).T @ _NDArray_7, FALSE\n", - ")\n", - "(\n", - " (_NDArray_1 - (_NDArray_3 @ _NDArray_4))\n", - " @ (\n", - " _NDArray_7\n", - " @ _TupleNDArray_2[Int(2)].T[\n", - " IndexKey.multi_axis(\n", - " _MultiAxisIndexKey_1\n", - " + MultiAxisIndexKey(\n", - " MultiAxisIndexKeyItem.slice(\n", - " Slice(\n", - " OptionalInt.none,\n", - " OptionalInt.some(\n", - " sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n", - " .to_value()\n", - " .to_int\n", - " ),\n", - " )\n", - " )\n", - " )\n", - " )\n", - " ]\n", - " )\n", - ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(Int(1))))))]" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "
_NDArray_1 = NDArray.var("X")\n",
+       "assume_dtype(_NDArray_1, DType.float64)\n",
+       "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n",
+       "assume_isfinite(_NDArray_1)\n",
+       "_NDArray_2 = NDArray.var("y")\n",
+       "assume_dtype(_NDArray_2, DType.int64)\n",
+       "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n",
+       "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n",
+       "_NDArray_3 = asarray(reshape(asarray(_NDArray_2), TupleInt(Int(-1))))\n",
+       "_NDArray_4 = astype(unique_counts(_NDArray_3)[Int(1)], asarray(_NDArray_1).dtype) / NDArray.scalar(Value.float(Float(1000000.0)))\n",
+       "_NDArray_5 = zeros(\n",
+       "    TupleInt(unique_inverse(_NDArray_3)[Int(0)].shape[Int(0)]) + TupleInt(asarray(_NDArray_1).shape[Int(1)]),\n",
+       "    OptionalDType.some(asarray(_NDArray_1).dtype),\n",
+       "    OptionalDevice.some(asarray(_NDArray_1).device),\n",
+       ")\n",
+       "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n",
+       "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n",
+       "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n",
+       "_NDArray_5[_IndexKey_1] = mean(asarray(_NDArray_1)[ndarray_index(unique_inverse(_NDArray_3)[Int(1)] == NDArray.scalar(Value.int(Int(0))))], _OptionalIntOrTuple_1)\n",
+       "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n",
+       "_NDArray_5[_IndexKey_2] = mean(asarray(_NDArray_1)[ndarray_index(unique_inverse(_NDArray_3)[Int(1)] == NDArray.scalar(Value.int(Int(1))))], _OptionalIntOrTuple_1)\n",
+       "_NDArray_6 = unique_values(concat(TupleNDArray(unique_values(asarray(_NDArray_3)))))\n",
+       "_NDArray_7 = concat(\n",
+       "    TupleNDArray(asarray(_NDArray_1)[ndarray_index(_NDArray_3 == _NDArray_6[IndexKey.int(Int(0))])] - _NDArray_5[_IndexKey_1])\n",
+       "    + TupleNDArray(asarray(_NDArray_1)[ndarray_index(_NDArray_3 == _NDArray_6[IndexKey.int(Int(1))])] - _NDArray_5[_IndexKey_2]),\n",
+       "    OptionalInt.some(Int(0)),\n",
+       ")\n",
+       "_NDArray_8 = std(_NDArray_7, _OptionalIntOrTuple_1)\n",
+       "_NDArray_8[ndarray_index(std(_NDArray_7, _OptionalIntOrTuple_1) == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n",
+       "_TupleNDArray_1 = svd(\n",
+       "    sqrt(asarray(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(asarray(_NDArray_1).shape[Int(0)] - _NDArray_6.shape[Int(0)]))))) * (_NDArray_7 / _NDArray_8), FALSE\n",
+       ")\n",
+       "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n",
+       "_NDArray_9 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_8).T / _TupleNDArray_1[\n",
+       "    Int(1)\n",
+       "][IndexKey.slice(_Slice_1)]\n",
+       "_TupleNDArray_2 = svd(\n",
+       "    (\n",
+       "        sqrt(\n",
+       "            (NDArray.scalar(Value.int(asarray(_NDArray_1).shape[Int(0)])) * _NDArray_4)\n",
+       "            * NDArray.scalar(Value.float(Float(1.0) / Float.from_int(_NDArray_6.shape[Int(0)] - Int(1))))\n",
+       "        )\n",
+       "        * (_NDArray_5 - (_NDArray_4 @ _NDArray_5)).T\n",
+       "    ).T\n",
+       "    @ _NDArray_9,\n",
+       "    FALSE,\n",
+       ")\n",
+       "(\n",
+       "    (asarray(_NDArray_1) - (_NDArray_4 @ _NDArray_5))\n",
+       "    @ (\n",
+       "        _NDArray_9\n",
+       "        @ _TupleNDArray_2[Int(2)].T[\n",
+       "            IndexKey.multi_axis(\n",
+       "                _MultiAxisIndexKey_1\n",
+       "                + MultiAxisIndexKey(\n",
+       "                    MultiAxisIndexKeyItem.slice(\n",
+       "                        Slice(\n",
+       "                            OptionalInt.none,\n",
+       "                            OptionalInt.some(\n",
+       "                                sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n",
+       "                                .to_value()\n",
+       "                                .to_int\n",
+       "                            ),\n",
+       "                        )\n",
+       "                    )\n",
+       "                )\n",
+       "            )\n",
+       "        ]\n",
+       "    )\n",
+       ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(_NDArray_6.shape[Int(0)] - Int(1))))))]\n",
+       "
\n" ], - "source": [ - "egraph = EGraph([array_api_module])\n", - "egraph.register(X_r2)\n", - "egraph.run(10000)\n", - "X_r2_optimized = egraph.extract(X_r2)\n", - "X_r2_optimized" - ] - }, - { - "cell_type": "markdown", - "id": "30ea4ea4", - "metadata": {}, - "source": [ - "We see that for example expressions that referenced the shape of our input arrays have been resolved to their\n", - "values.\n", - "\n", - "We can also take a look at the e-graph itself, even though it's quite large, where we can see that equivalent\n", - "expressions show up in the same group, or \"e-class\":\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "6417b9e5", - "metadata": {}, - "outputs": [ - { - "data": { - "image/svg+xml": [ - "\n", - "\n", - "\n", - "\n", - "outer_cluster_32\n", - "\n", - "\n", - "cluster_32\n", - "\n", - "\n", - "\n", - "outer_cluster_48\n", - "\n", - "\n", - "cluster_48\n", - "\n", - "\n", - "\n", - "outer_cluster_92\n", - "\n", - "\n", - "cluster_92\n", - "\n", - "\n", - "\n", - "outer_cluster_155\n", - "\n", - "\n", - "cluster_155\n", - "\n", - "\n", - "\n", - "outer_cluster_34\n", - "\n", - "\n", - "cluster_34\n", - "\n", - "\n", - "\n", - "outer_cluster_91\n", - "\n", - "\n", - "cluster_91\n", - "\n", - "\n", - "\n", - "outer_cluster_72\n", - "\n", - "\n", - "cluster_72\n", - "\n", - "\n", - "\n", - "outer_cluster_190\n", - "\n", - "\n", - "cluster_190\n", - "\n", - "\n", - "\n", - "outer_cluster_147\n", - "\n", - "\n", - "cluster_147\n", - "\n", - "\n", - "\n", - "outer_cluster_58\n", - "\n", - "\n", - "cluster_58\n", - "\n", - "\n", - "\n", - "outer_cluster_62\n", - "\n", - "\n", - "cluster_62\n", - "\n", - "\n", - "\n", - "outer_cluster_143\n", - "\n", - "\n", - "cluster_143\n", - "\n", - "\n", - "\n", - "outer_cluster_75\n", - "\n", - "\n", - "cluster_75\n", - "\n", - "\n", - "\n", - "outer_cluster_118\n", - "\n", - "\n", - "cluster_118\n", - "\n", - "\n", - "\n", - "outer_cluster_105\n", - "\n", - "\n", - "cluster_105\n", - "\n", - "\n", - "\n", - "outer_cluster_71\n", - "\n", - "\n", - "cluster_71\n", - "\n", - "\n", - "\n", - "outer_cluster_141\n", - "\n", - "\n", - "cluster_141\n", - "\n", - "\n", - "\n", - "outer_cluster_142\n", - "\n", - "\n", - "cluster_142\n", - "\n", - "\n", - "\n", - "outer_cluster_52\n", - "\n", - "\n", - "cluster_52\n", - "\n", - "\n", - "\n", - "outer_cluster_56\n", - "\n", - "\n", - "cluster_56\n", - "\n", - "\n", - "\n", - "outer_cluster_188\n", - "\n", - "\n", - "cluster_188\n", - "\n", - "\n", - "\n", - "outer_cluster_69\n", - "\n", - "\n", - "cluster_69\n", - "\n", - "\n", - "\n", - "outer_cluster_178\n", - "\n", - "\n", - "cluster_178\n", - "\n", - "\n", - "\n", - "outer_cluster_140\n", - "\n", - "\n", - "cluster_140\n", - "\n", - "\n", - "\n", - "outer_cluster_187\n", - "\n", - "\n", - "cluster_187\n", - "\n", - "\n", - "\n", - "outer_cluster_95\n", - "\n", - "\n", - "cluster_95\n", - "\n", - "\n", - "\n", - "outer_cluster_12\n", - "\n", - "\n", - "cluster_12\n", - "\n", - "\n", - "\n", - "outer_cluster_102\n", - "\n", - "\n", - "cluster_102\n", - "\n", - "\n", - "\n", - "outer_cluster_67\n", - "\n", - "\n", - "cluster_67\n", - "\n", - "\n", - "\n", - "outer_cluster_115\n", - "\n", - "\n", - "cluster_115\n", - "\n", - "\n", - "\n", - "outer_cluster_63\n", - "\n", - "\n", - "cluster_63\n", - "\n", - "\n", - "\n", - "outer_cluster_127\n", - "\n", - "\n", - "cluster_127\n", - "\n", - "\n", - "\n", - "outer_cluster_146\n", - "\n", - "\n", - "cluster_146\n", - "\n", - "\n", - "\n", - "outer_cluster_109\n", - "\n", - "\n", - "cluster_109\n", - "\n", - "\n", - "\n", - "outer_cluster_191\n", - "\n", - "\n", - "cluster_191\n", - "\n", - "\n", - "\n", - "outer_cluster_37\n", - "\n", - "\n", - "cluster_37\n", - "\n", - "\n", - "\n", - "outer_cluster_79\n", - "\n", - "\n", - "cluster_79\n", - "\n", - "\n", - "\n", - "outer_cluster_122\n", - "\n", - "\n", - "cluster_122\n", - "\n", - "\n", - "\n", - "outer_cluster_163\n", - "\n", - "\n", - "cluster_163\n", - "\n", - "\n", - "\n", - "outer_cluster_145\n", - "\n", - "\n", - "cluster_145\n", - "\n", - "\n", - "\n", - "outer_cluster_106\n", - "\n", - "\n", - "cluster_106\n", - "\n", - "\n", - "\n", - "outer_cluster_2\n", - "\n", - "\n", - "cluster_2\n", - "\n", - "\n", - "\n", - "outer_cluster_149\n", - "\n", - "\n", - "cluster_149\n", - "\n", - "\n", - "\n", - "outer_cluster_126\n", - "\n", - "\n", - "cluster_126\n", - "\n", - "\n", - "\n", - "outer_cluster_110\n", - "\n", - "\n", - "cluster_110\n", - "\n", - "\n", - "\n", - "outer_cluster_131\n", - "\n", - "\n", - "cluster_131\n", - "\n", - "\n", - "\n", - "outer_cluster_171\n", - "\n", - "\n", - "cluster_171\n", - "\n", - "\n", - "\n", - "outer_cluster_99\n", - "\n", - "\n", - "cluster_99\n", - "\n", - "\n", - "\n", - "outer_cluster_135\n", - "\n", - "\n", - "cluster_135\n", - "\n", - "\n", - "\n", - "outer_cluster_182\n", - "\n", - "\n", - "cluster_182\n", - "\n", - "\n", - "\n", - "outer_cluster_8\n", - "\n", - "\n", - "cluster_8\n", - "\n", - "\n", - "\n", - "outer_cluster_78\n", - "\n", - "\n", - "cluster_78\n", - "\n", - "\n", - "\n", - "outer_cluster_167\n", - "\n", - "\n", - "cluster_167\n", - "\n", - "\n", - "\n", - "outer_cluster_172\n", - "\n", - "\n", - "cluster_172\n", - "\n", - "\n", - "\n", - "outer_cluster_169\n", - "\n", - "\n", - "cluster_169\n", - "\n", - "\n", - "\n", - "outer_cluster_36\n", - "\n", - "\n", - "cluster_36\n", - "\n", - "\n", - "\n", - "outer_cluster_76\n", - "\n", - "\n", - "cluster_76\n", - "\n", - "\n", - "\n", - "outer_cluster_61\n", - "\n", - "\n", - "cluster_61\n", - "\n", - "\n", - "\n", - "outer_cluster_157\n", - "\n", - "\n", - "cluster_157\n", - "\n", - "\n", - "\n", - "outer_cluster_173\n", - "\n", - "\n", - "cluster_173\n", - "\n", - "\n", - "\n", - "outer_cluster_164\n", - "\n", - "\n", - "cluster_164\n", - "\n", - "\n", - "\n", - "outer_cluster_33\n", - "\n", - "\n", - "cluster_33\n", - "\n", - "\n", - "\n", - "outer_cluster_83\n", - "\n", - "\n", - "cluster_83\n", - "\n", - "\n", - "\n", - "outer_cluster_116\n", - "\n", - "\n", - "cluster_116\n", - "\n", - "\n", - "\n", - "outer_cluster_168\n", - "\n", - "\n", - "cluster_168\n", - "\n", - "\n", - "\n", - "outer_cluster_100\n", - "\n", - "\n", - "cluster_100\n", - "\n", - "\n", - "\n", - "outer_cluster_108\n", - "\n", - "\n", - "cluster_108\n", - "\n", - "\n", - "\n", - "outer_cluster_181\n", - "\n", - "\n", - "cluster_181\n", - "\n", - "\n", - "\n", - "outer_cluster_90\n", - "\n", - "\n", - "cluster_90\n", - "\n", - "\n", - "\n", - "outer_cluster_153\n", - "\n", - "\n", - "cluster_153\n", - "\n", - "\n", - "\n", - "outer_cluster_175\n", - "\n", - "\n", - "cluster_175\n", - "\n", - "\n", - "\n", - "outer_cluster_137\n", - "\n", - "\n", - "cluster_137\n", - "\n", - "\n", - "\n", - "outer_cluster_89\n", - "\n", - "\n", - "cluster_89\n", - "\n", - "\n", - "\n", - "outer_cluster_82\n", - "\n", - "\n", - "cluster_82\n", - "\n", - "\n", - "\n", - "outer_cluster_44\n", - "\n", - "\n", - "cluster_44\n", - "\n", - "\n", - "\n", - "outer_cluster_180\n", - "\n", - "\n", - "cluster_180\n", - "\n", - "\n", - "\n", - "outer_cluster_189\n", - "\n", - "\n", - "cluster_189\n", - "\n", - "\n", - "\n", - "outer_cluster_179\n", - "\n", - "\n", - "cluster_179\n", - "\n", - "\n", - "\n", - "outer_cluster_70\n", - "\n", - "\n", - "cluster_70\n", - "\n", - "\n", - "\n", - "outer_cluster_57\n", - "\n", - "\n", - "cluster_57\n", - "\n", - "\n", - "\n", - "outer_cluster_121\n", - "\n", - "\n", - "cluster_121\n", - "\n", - "\n", - "\n", - "outer_cluster_31\n", - "\n", - "\n", - "cluster_31\n", - "\n", - "\n", - "\n", - "outer_cluster_123\n", - "\n", - "\n", - "cluster_123\n", - "\n", - "\n", - "\n", - "outer_cluster_68\n", - "\n", - "\n", - "cluster_68\n", - "\n", - "\n", - "\n", - "outer_cluster_50\n", - "\n", - "\n", - "cluster_50\n", - "\n", - "\n", - "\n", - "outer_cluster_151\n", - "\n", - "\n", - "cluster_151\n", - "\n", - "\n", - "\n", - "outer_cluster_77\n", - "\n", - "\n", - "cluster_77\n", - "\n", - "\n", - "\n", - "outer_cluster_74\n", - "\n", - "\n", - "cluster_74\n", - "\n", - "\n", - "\n", - "outer_cluster_101\n", - "\n", - "\n", - "cluster_101\n", - "\n", - "\n", - "\n", - "outer_cluster_152\n", - "\n", - "\n", - "cluster_152\n", - "\n", - "\n", - "\n", - "outer_cluster_130\n", - "\n", - "\n", - "cluster_130\n", - "\n", - "\n", - "\n", - "outer_cluster_161\n", - "\n", - "\n", - "cluster_161\n", - "\n", - "\n", - "\n", - "outer_cluster_148\n", - "\n", - "\n", - "cluster_148\n", - "\n", - "\n", - "\n", - "outer_cluster_80\n", - "\n", - "\n", - "cluster_80\n", - "\n", - "\n", - "\n", - "outer_cluster_111\n", - "\n", - "\n", - "cluster_111\n", - "\n", - "\n", - "\n", - "outer_cluster_183\n", - "\n", - "\n", - "cluster_183\n", - "\n", - "\n", - "\n", - "outer_cluster_59\n", - "\n", - "\n", - "cluster_59\n", - "\n", - "\n", - "\n", - "outer_cluster_159\n", - "\n", - "\n", - "cluster_159\n", - "\n", - "\n", - "\n", - "outer_cluster_103\n", - "\n", - "\n", - "cluster_103\n", - "\n", - "\n", - "\n", - "outer_cluster_117\n", - "\n", - "\n", - "cluster_117\n", - "\n", - "\n", - "\n", - "outer_cluster_158\n", - "\n", - "\n", - "cluster_158\n", - "\n", - "\n", - "\n", - "outer_cluster_87\n", - "\n", - "\n", - "cluster_87\n", - "\n", - "\n", - "\n", - "outer_cluster_96\n", - "\n", - "\n", - "cluster_96\n", - "\n", - "\n", - "\n", - "outer_cluster_98\n", - "\n", - "\n", - "cluster_98\n", - "\n", - "\n", - "\n", - "outer_cluster_166\n", - "\n", - "\n", - "cluster_166\n", - "\n", - "\n", - "\n", - "outer_cluster_133\n", - "\n", - "\n", - "cluster_133\n", - "\n", - "\n", - "\n", - "outer_cluster_184\n", - "\n", - "\n", - "cluster_184\n", - "\n", - "\n", - "\n", - "outer_cluster_107\n", - "\n", - "\n", - "cluster_107\n", - "\n", - "\n", - "\n", - "outer_cluster_162\n", - "\n", - "\n", - "cluster_162\n", - "\n", - "\n", - "\n", - "outer_cluster_144\n", - "\n", - "\n", - "cluster_144\n", - "\n", - "\n", - "\n", - "outer_cluster_170\n", - "\n", - "\n", - "cluster_170\n", - "\n", - "\n", - "\n", - "outer_cluster_160\n", - "\n", - "\n", - "cluster_160\n", - "\n", - "\n", - "\n", - "outer_cluster_16\n", - "\n", - "\n", - "cluster_16\n", - "\n", - "\n", - "\n", - "outer_cluster_47\n", - "\n", - "\n", - "cluster_47\n", - "\n", - "\n", - "\n", - "outer_cluster_49\n", - "\n", - "\n", - "cluster_49\n", - "\n", - "\n", - "\n", - "outer_cluster_138\n", - "\n", - "\n", - "cluster_138\n", - "\n", - "\n", - "\n", - "outer_cluster_185\n", - "\n", - "\n", - "cluster_185\n", - "\n", - "\n", - "\n", - "outer_cluster_176\n", - "\n", - "\n", - "cluster_176\n", - "\n", - "\n", - "\n", - "outer_cluster_65\n", - "\n", - "\n", - "cluster_65\n", - "\n", - "\n", - "\n", - "outer_cluster_Int_to_py-7586556743040283621-value\n", - "\n", - "\n", - "cluster_Int_to_py-7586556743040283621-value\n", - "\n", - "\n", - "\n", - "outer_cluster_Int_to_py-11951456526892775522-value\n", - "\n", - "\n", - "cluster_Int_to_py-11951456526892775522-value\n", - "\n", - "\n", - "\n", - "outer_cluster_Int_to_py-6079675520328773069-value\n", - "\n", - "\n", - "cluster_Int_to_py-6079675520328773069-value\n", - "\n", - "\n", - "\n", - "outer_cluster_Int_to_py-103947256882385308-value\n", - "\n", - "\n", - "cluster_Int_to_py-103947256882385308-value\n", - "\n", - "\n", - "\n", - "outer_cluster_Int_to_py-5092353580987650850-value\n", - "\n", - "\n", - "cluster_Int_to_py-5092353580987650850-value\n", - "\n", - "\n", - "\n", - "outer_cluster_Int_to_py-1870696621799859130-value\n", - "\n", - "\n", - "cluster_Int_to_py-1870696621799859130-value\n", - "\n", - "\n", - "\n", - "outer_cluster_Boolean_to_py-155920885323577962-value\n", - "\n", - "\n", - "cluster_Boolean_to_py-155920885323577962-value\n", - "\n", - "\n", - "\n", - "outer_cluster_Int_to_py-12938778466233897741-value\n", - "\n", - "\n", - "cluster_Int_to_py-12938778466233897741-value\n", - "\n", - "\n", - "\n", - "outer_cluster_139\n", - "\n", - "\n", - "cluster_139\n", - "\n", - "\n", - "\n", - "outer_cluster_177\n", - "\n", - "\n", - "cluster_177\n", - "\n", - "\n", - "\n", - "outer_cluster_186\n", - "\n", - "\n", - "cluster_186\n", - "\n", - "\n", - "\n", - "outer_cluster_43\n", - "\n", - "\n", - "cluster_43\n", - "\n", - "\n", - "\n", - "outer_cluster_203\n", - "\n", - "\n", - "cluster_203\n", - "\n", - "\n", - "\n", - "outer_cluster_46\n", - "\n", - "\n", - "cluster_46\n", - "\n", - "\n", - "\n", - "outer_cluster_212\n", - "\n", - "\n", - "cluster_212\n", - "\n", - "\n", - "\n", - "outer_cluster_42\n", - "\n", - "\n", - "cluster_42\n", - "\n", - "\n", - "\n", - "outer_cluster_45\n", - "\n", - "\n", - "cluster_45\n", - "\n", - "\n", - "\n", - "outer_cluster_38\n", - "\n", - "\n", - "cluster_38\n", - "\n", - "\n", - "\n", - "outer_cluster_104\n", - "\n", - "\n", - "cluster_104\n", - "\n", - "\n", - "\n", - "outer_cluster_112\n", - "\n", - "\n", - "cluster_112\n", - "\n", - "\n", - "\n", - "outer_cluster_113\n", - "\n", - "\n", - "cluster_113\n", - "\n", - "\n", - "\n", - "outer_cluster_165\n", - "\n", - "\n", - "cluster_165\n", - "\n", - "\n", - "\n", - "outer_cluster_85\n", - "\n", - "\n", - "cluster_85\n", - "\n", - "\n", - "\n", - "outer_cluster_124\n", - "\n", - "\n", - "cluster_124\n", - "\n", - "\n", - "\n", - "outer_cluster_30\n", - "\n", - "\n", - "cluster_30\n", - "\n", - "\n", - "\n", - "outer_cluster_19\n", - "\n", - "\n", - "cluster_19\n", - "\n", - "\n", - "\n", - "outer_cluster_201\n", - "\n", - "\n", - "cluster_201\n", - "\n", - "\n", - "\n", - "outer_cluster_198\n", - "\n", - "\n", - "cluster_198\n", - "\n", - "\n", - "\n", - "outer_cluster_22\n", - "\n", - "\n", - "cluster_22\n", - "\n", - "\n", - "\n", - "outer_cluster_greater_zero-1143242824664700181-value\n", - "\n", - "\n", - "cluster_greater_zero-1143242824664700181-value\n", - "\n", - "\n", - "\n", - "outer_cluster_greater_zero-13770179520251441998-value\n", - "\n", - "\n", - "cluster_greater_zero-13770179520251441998-value\n", - "\n", - "\n", - "\n", - "outer_cluster_greater_zero-14757501459592564217-value\n", - "\n", - "\n", - "cluster_greater_zero-14757501459592564217-value\n", - "\n", - "\n", - "\n", - "outer_cluster_greater_zero-2598150418935018079-value\n", - "\n", - "\n", - "cluster_greater_zero-2598150418935018079-value\n", - "\n", - "\n", - "\n", - "outer_cluster_greater_zero-12107377412216353484-value\n", - "\n", - "\n", - "cluster_greater_zero-12107377412216353484-value\n", - "\n", - "\n", - "\n", - "outer_cluster_93\n", - "\n", - "\n", - "cluster_93\n", - "\n", - "\n", - "\n", - "outer_cluster_156\n", - "\n", - "\n", - "cluster_156\n", - "\n", - "\n", - "\n", - "outer_cluster_150\n", - "\n", - "\n", - "cluster_150\n", - "\n", - "\n", - "\n", - "outer_cluster_200\n", - "\n", - "\n", - "cluster_200\n", - "\n", - "\n", - "\n", - "outer_cluster_136\n", - "\n", - "\n", - "cluster_136\n", - "\n", - "\n", - "\n", - "outer_cluster_210\n", - "\n", - "\n", - "cluster_210\n", - "\n", - "\n", - "\n", - "outer_cluster_213\n", - "\n", - "\n", - "cluster_213\n", - "\n", - "\n", - "\n", - "outer_cluster_35\n", - "\n", - "\n", - "cluster_35\n", - "\n", - "\n", - "\n", - "outer_cluster_197\n", - "\n", - "\n", - "cluster_197\n", - "\n", - "\n", - "\n", - "outer_cluster_174\n", - "\n", - "\n", - "cluster_174\n", - "\n", - "\n", - "\n", - "outer_cluster_208\n", - "\n", - "\n", - "cluster_208\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_dtype-15121139857639374588:s->assume_isfinite-10080759905092916392\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_isfinite-10080759905092916392:s->assume_shape-14591484260056516843\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_dtype-10080759905092916392:s->assume_shape-14591484260056516843\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_shape-14591484260056516843:s->assume_dtype-3429551472952562336\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_shape-14591484260056516843:s->NDArray_shape-15121139857639374588\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_dtype-11743562013128004906:s->assume_dtype-3429551472952562336\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_dtype-3429551472952562336:s->NDArray_dtype-10080759905092916392\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_device-15121139857639374588:s->asarray-9510298863856844727\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "asarray-9510298863856844727:s->assume_isfinite-10080759905092916392\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float___truediv__-12808993487988576005:s->Float_rational-0\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float___truediv__-12808993487988576005:s->Float_from_int-11951456526892775522\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float_from_int-11951456526892775522:s->Int___sub__-2601583573127157282\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float_from_int-12938778466233897741:s->TupleInt_length-11379923615081194535\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt_length-11379923615081194535:s->NDArray_shape-7742477628363861583\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float___truediv__-5949890542083451333:s->Float_from_int-12938778466233897741\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float___truediv__-5949890542083451333:s->Float___truediv__-5949890542083451333\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___sub__-2601583573127157282:s->Int___init__-16347205588787662656\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___sub__-2601583573127157282:s->Int___init__-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-11068081844434038611:s->MultiAxisIndexKey___add__-7546443524583315781\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-7546443524583315781:s->MultiAxisIndexKey___init__-9353306107957757443\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-7546443524583315781:s->MultiAxisIndexKey___init__-17771263905015585321\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-2961965818023366657:s->MultiAxisIndexKey___add__-9019874688858188702\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-9019874688858188702:s->MultiAxisIndexKey___init__-9353306107957757443\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-9019874688858188702:s->MultiAxisIndexKey___init__-9665147878604913367\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_slice-4520820669176069863:s->Slice___init__-15501507093852132239\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Slice___init__-15501507093852132239:s->OptionalInt_some-11224002729757616573\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-2650124047376210733:s->MultiAxisIndexKey___add__-4155431249018709085\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-4155431249018709085:s->MultiAxisIndexKey___init__-9353306107957757443\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-4155431249018709085:s->MultiAxisIndexKey___init__-4312926155411299247\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-7690503999922668929:s->NDArray___eq__-17968234112188297122\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-17968234112188297122:s->TupleNDArray___getitem__-10045558824545728354\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-17968234112188297122:s->NDArray___getitem__-6343722845416298339\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-3689419615158525606:s->MultiAxisIndexKey___add__-10696952293987308628\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-10696952293987308628:s->MultiAxisIndexKey___init__-9353306107957757443\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-10696952293987308628:s->MultiAxisIndexKey___init__-10392601675740072316\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-10236680790416494354:s->NDArray___eq__-7887474207095380730\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-7887474207095380730:s->NDArray___getitem__-16424482750509214731\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-7887474207095380730:s->TupleNDArray___getitem__-10045558824545728354\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-4468847040734877209:s->NDArray___eq__-3677844317228415595\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-3677844317228415595:s->NDArray_scalar-3845340500482103568\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-3677844317228415595:s->std-4851945112178408602\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_int-12938778466233897741:s->Int___sub__-11477953740632672431\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___sub__-11477953740632672431:s->TupleValue_length-883374682458736911\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___sub__-11477953740632672431:s->Int___add__-17495654355659155035\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-9457253364840142751:s->NDArray___eq__-5948126446311695931\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-5948126446311695931:s->asarray-17776165865978447989\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-5948126446311695931:s->NDArray_scalar-3845340500482103568\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-1091269196223507527:s->NDArray___eq__-14314110614928331155\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-14314110614928331155:s->NDArray_scalar-14757501459592564217\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-14314110614928331155:s->assume_value_one_of-5323778840018127892\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-5456168980075999428:s->MultiAxisIndexKey___add__-8188473634840644445\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-8188473634840644445:s->MultiAxisIndexKey___init__-9353306107957757443\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-8188473634840644445:s->MultiAxisIndexKey___init__-12159351040657546138\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-7742477628363861583:s->reshape-4112525690760736104\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue_length-51973628441192654:s->TupleValue___init__-14757501459592564217\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___init__-14757501459592564217:s->TupleValue___getitem__-4148863126349750477\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue_length-883374682458736911:s->TupleValue___init__-3845340500482103568\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___init__-3845340500482103568:s->TupleValue___getitem__-7786309113067083429\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___add__-17495654355659155035:s->Int___sub__-11477953740632672431\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___add__-17495654355659155035:s->Int___init__-5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_to_int-7118971088111087942:s->NDArray_to_value-1247190081547085489\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_to_value-1247190081547085489:s->sum-1681433789052220133\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_to_int-5352221723193614120:s->NDArray_to_value-17927184790339163283\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_to_value-17927184790339163283:s->sum-1955564354691009820\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue_length-467762655970733886:s->TupleValue___add__-15259460202689358531\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___add__-15259460202689358531:s->TupleValue___init__-14757501459592564217\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___add__-15259460202689358531:s->TupleValue___init__-3845340500482103568\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue_length-18083105675662741245:s->possible_values-12211324669098738792\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "possible_values-12211324669098738792:s->NDArray_index-12579319251068649370\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___getitem__-14078601210367663714:s->NDArray_shape-12782857580910319779\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-12782857580910319779:s->unique_values-12782857580910319779\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___getitem__-11605336705429392564:s->NDArray_shape-10080759905092916392\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-10080759905092916392:s->assume_shape-14591484260056516843\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___getitem__-12686509587440430679:s->TupleInt___init__-103947256882385308\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___init__-103947256882385308:s->Int___init__-6755155689022739364\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___getitem__-7967890718712059612:s->TupleValue_length-51973628441192654\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___getitem__-7967890718712059612:s->TupleInt___add__-13243224121832505654\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___add__-13243224121832505654:s->TupleInt___init__-103947256882385308\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___add__-13243224121832505654:s->NDArray_shape-1714775736476281168\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-12159351040657546138:s->MultiAxisIndexKeyItem_slice-6287570034093543685\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-9665147878604913367:s->MultiAxisIndexKeyItem_slice-3793366872040910914\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_slice-6287570034093543685:s->Slice___init__-14445438978175812750\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-17771263905015585321:s->MultiAxisIndexKeyItem_int-12938778466233897741\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_int-12938778466233897741:s->TupleValue_length-883374682458736911\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-10392601675740072316:s->MultiAxisIndexKeyItem_slice-4520820669176069863\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_slice-4520820669176069863:s->Slice___init__-15501507093852132239\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_slice-3793366872040910914:s->Slice___init__-1162291712589082458\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Slice___init__-14445438978175812750:s->OptionalInt_some-12990752094675090395\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Slice___init__-1162291712589082458:s->OptionalInt_some-12938778466233897741\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-11120055472875231265:s->Value_float-5248274466311228812\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_float-5248274466311228812:s->Float_rational-17615343019692007359\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "asarray-7902703286805427734:s->asarray-7902703286805427734\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-17483047916985507424:s->IndexKey_multi_axis-2650124047376210733\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-17483047916985507424:s->NDArray___setitem__-18325169333216085054\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-18325169333216085054:s->IndexKey_multi_axis-11068081844434038611\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-18325169333216085054:s->NDArray___setitem__-7453141863274628760\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-18325169333216085054:s->mean-3476503888447580293\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "mean-9206860573968271485:s->NDArray___getitem__-16307929054953181812\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "mean-9206860573968271485:s->OptionalIntOrTuple_some-6859102945905124672\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-16307929054953181812:s->asarray-9510298863856844727\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-16307929054953181812:s->ndarray_index-7690503999922668929\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "concat-9071020324919791953:s->TupleNDArray___add__-17612194977553982959\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___add__-17612194977553982959:s->TupleNDArray___init__-14497633317386600947\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___add__-17612194977553982959:s->TupleNDArray___init__-6131649148769965723\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-18135092377765138894:s->TupleValue_length-51973628441192654\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-18135092377765138894:s->svd-7253966389981509278\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "svd-7253966389981509278:s->NDArray___mul__-8455018010728142919\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_T-2858018561140981349:s->NDArray___truediv__-11279504549742320031\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-11279504549742320031:s->NDArray___setitem__-5767087113385015795\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-11279504549742320031:s->NDArray___getitem__-9914932780259612220\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-18178625676753040942:s->assume_isfinite-10080759905092916392\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-18178625676753040942:s->ndarray_index-1091269196223507527\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-11026489642259430172:s->IndexKey_multi_axis-2961965818023366657\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-11026489642259430172:s->NDArray___matmul__-7132500556515696557\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-7132500556515696557:s->NDArray___sub__-8877293197236476153\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-7132500556515696557:s->NDArray___matmul__-10968585808826125111\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-15656725660214344740:s->astype-6261542238027864055\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-15656725660214344740:s->NDArray_scalar-2598150418935018079\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "astype-6261542238027864055:s->NDArray_dtype-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "astype-6261542238027864055:s->TupleNDArray___getitem__-15957548086918070248\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-2598150418935018079:s->Value_float-15173113486080567242\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-9557034512502171054:s->NDArray___setitem__-18325169333216085054\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-9557034512502171054:s->NDArray___truediv__-15656725660214344740\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-9788377807842481490:s->concat-9071020324919791953\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-9788377807842481490:s->NDArray___setitem__-5767087113385015795\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-5767087113385015795:s->ndarray_index-4468847040734877209\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-5767087113385015795:s->NDArray_scalar-12107377412216353484\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-5767087113385015795:s->std-4851945112178408602\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_T-10444575304181264970:s->NDArray___mul__-7696624279617524538\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-7696624279617524538:s->NDArray_T-17147757364762811680\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-7696624279617524538:s->ndarray-sqrt-5404195351634806774\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-9914932780259612220:s->IndexKey_multi_axis-3689419615158525606\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-9914932780259612220:s->TupleNDArray___getitem__-1818913068061409678\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-14757501459592564217:s->TupleValue___getitem__-9658389681233211557\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-9658389681233211557:s->TupleValue___init__-14757501459592564217\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-16424482750509214731:s->IndexKey_int-12938778466233897741\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-16424482750509214731:s->concat-430064524623572644\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "concat-430064524623572644:s->TupleNDArray___init__-12782857580910319779\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-3215265837560371319:s->NDArray_T-2858018561140981349\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-3215265837560371319:s->NDArray___getitem__-11494903289568215254\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-11494903289568215254:s->IndexKey_slice-4520820669176069863\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-11494903289568215254:s->TupleNDArray___getitem__-18135092377765138894\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-1818913068061409678:s->TupleValue_length-467762655970733886\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-1818913068061409678:s->svd-7253966389981509278\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-2205987174022554874:s->IndexKey_multi_axis-11068081844434038611\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-2205987174022554874:s->NDArray___setitem__-18325169333216085054\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___gt__-15651908559655936539:s->TupleNDArray___getitem__-18135092377765138894\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___gt__-15651908559655936539:s->NDArray_scalar-1143242824664700181\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___gt__-8664676620264668937:s->TupleNDArray___getitem__-17539377729349800285\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___gt__-8664676620264668937:s->NDArray___mul__-8440009558605893705\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-17539377729349800285:s->TupleValue_length-883374682458736911\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-17539377729349800285:s->svd-2189404700831293460\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-8440009558605893705:s->NDArray_scalar-1143242824664700181\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-8440009558605893705:s->NDArray___getitem__-17758114586016463110\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "asarray-17776165865978447989:s->reshape-4112525690760736104\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-3845340500482103568:s->TupleValue___getitem__-1353837537593392198\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "sum-1955564354691009820:s->astype-14592420363448682842\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "astype-14592420363448682842:s->NDArray___gt__-15651908559655936539\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-13476223401931994896:s->IndexKey_multi_axis-5456168980075999428\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-13476223401931994896:s->NDArray_T-15484955256727723166\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_T-15484955256727723166:s->TupleNDArray___getitem__-10680274783444675613\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-15121139857639374588:s->assume_isfinite-10080759905092916392\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-7453141863274628760:s->IndexKey_multi_axis-2650124047376210733\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-7453141863274628760:s->mean-9206860573968271485\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-7453141863274628760:s->zeros-16505489609336576318\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "mean-3476503888447580293:s->OptionalIntOrTuple_some-6859102945905124672\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "mean-3476503888447580293:s->NDArray___getitem__-3836913244690017957\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-10680274783444675613:s->TupleValue_length-18083105675662741245\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-10680274783444675613:s->svd-2189404700831293460\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "astype-12468708834165933853:s->NDArray___gt__-8664676620264668937\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-15588902513610108474:s->NDArray_index-1182067134106770624\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-1182067134106770624:s->TupleNDArray___getitem__-17539377729349800285\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-17758114586016463110:s->TupleNDArray___getitem__-17539377729349800285\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_float-15173113486080567242:s->Float_rational-5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-3836913244690017957:s->assume_isfinite-10080759905092916392\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-3836913244690017957:s->ndarray_index-10236680790416494354\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-10045558824545728354:s->TupleInt_length-11379923615081194535\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-10045558824545728354:s->unique_inverse-7742477628363861583\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-6343722845416298339:s->NDArray_vector-467762655970733886\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-12107377412216353484:s->Value_float-6235596405652351031\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_float-6235596405652351031:s->Float___init__-10858178701590265856\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "sum-1681433789052220133:s->astype-12468708834165933853\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-13392291772433010205:s->NDArray_T-10444575304181264970\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-13392291772433010205:s->NDArray___truediv__-3215265837560371319\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-15957548086918070248:s->Int___sub__-11477953740632672431\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-15957548086918070248:s->unique_counts-7742477628363861583\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "reshape-4112525690760736104:s->reshape-4112525690760736104\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_value_one_of-5323778840018127892:s->TupleValue___add__-15259460202689358531\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_value_one_of-5323778840018127892:s->assume_shape-8316602628326787375\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_shape-8316602628326787375:s->TupleInt___init__-1870696621799859130\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "std-4851945112178408602:s->OptionalIntOrTuple_some-6859102945905124672\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "std-4851945112178408602:s->concat-9071020324919791953\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "svd-2189404700831293460:s->NDArray___matmul__-13392291772433010205\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "unique_counts-7742477628363861583:s->reshape-4112525690760736104\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-8455018010728142919:s->NDArray___truediv__-9788377807842481490\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-8455018010728142919:s->ndarray-sqrt-4416873412293684555\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray-sqrt-4416873412293684555:s->NDArray_scalar-11120055472875231265\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "zeros-16505489609336576318:s->TupleInt___add__-10752996994297486686\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "zeros-16505489609336576318:s->OptionalDType_some-3429551472952562336\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "zeros-16505489609336576318:s->OptionalDevice_some-5144327209428843504\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___add__-10752996994297486686:s->TupleInt___init__-103947256882385308\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___add__-10752996994297486686:s->TupleInt___init__-6079675520328773069\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalDType_some-3429551472952562336:s->NDArray_dtype-11743562013128004906\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalDevice_some-5144327209428843504:s->NDArray_device-15121139857639374588\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-13770179520251441998:s->Value_int-1870696621799859130\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_int-1870696621799859130:s->Int___init__-16347205588787662656\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-9812641508136405718:s->asarray-9510298863856844727\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-9812641508136405718:s->ndarray_index-9457253364840142751\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-4099386548708531027:s->NDArray___truediv__-15656725660214344740\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-4099386548708531027:s->NDArray_scalar-13770179520251441998\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_T-17147757364762811680:s->NDArray___sub__-1374586120005010617\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-1374586120005010617:s->NDArray___setitem__-18325169333216085054\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-1374586120005010617:s->NDArray___matmul__-9557034512502171054\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-8877293197236476153:s->assume_isfinite-10080759905092916392\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-8877293197236476153:s->NDArray___matmul__-9557034512502171054\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-9558798608273926456:s->NDArray___getitem__-18178625676753040942\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-9558798608273926456:s->NDArray___getitem__-2205987174022554874\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-10968585808826125111:s->NDArray___truediv__-3215265837560371319\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-10968585808826125111:s->NDArray___getitem__-13476223401931994896\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "unique_inverse-7742477628363861583:s->assume_value_one_of-5323778840018127892\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray-sqrt-5404195351634806774:s->NDArray___mul__-3756686807776082277\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-3756686807776082277:s->NDArray_scalar-12107377412216353484\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-3756686807776082277:s->NDArray___mul__-4099386548708531027\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-10430407918099810154:s->NDArray___getitem__-17483047916985507424\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-10430407918099810154:s->NDArray___getitem__-9812641508136405718\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___init__-12782857580910319779:s->unique_values-12782857580910319779\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-13683004811263061306:s->unique_inverse-7742477628363861583\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "unique_values-12782857580910319779:s->NDArray_vector-18083105675662741245\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_vector-18083105675662741245:s->possible_values-12211324669098738792\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "unique_values-7742477628363861583:s->asarray-17776165865978447989\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_vector-467762655970733886:s->possible_values-13042725723116283049\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "possible_values-13042725723116283049:s->NDArray_index-17067340853146132798\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-1353837537593392198:s->possible_values-12211324669098738792\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___init__-1870696621799859130:s->TupleInt___getitem__-11605336705429392564\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalInt_some-11224002729757616573:s->Value_to_int-5352221723193614120\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalInt_some-12938778466233897741:s->Int___init__-5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalInt_some-12990752094675090395:s->Value_to_int-7118971088111087942\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-11951456526892775522:s->Int___sub__-2601583573127157282\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-6079675520328773069:s->TupleValue_length-18083105675662741245\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-103947256882385308:s->TupleInt___getitem__-12686509587440430679\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-1870696621799859130:s->TupleInt___getitem__-11605336705429392564\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-12938778466233897741:s->TupleValue_length-883374682458736911\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-1714775736476281168:s->assume_shape-8316602628326787375\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___init__-6079675520328773069:s->TupleValue_length-467762655970733886\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___init__-12938778466233897741:s->TupleInt_length-11379923615081194535\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___init__-14497633317386600947:s->NDArray___sub__-10430407918099810154\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___init__-6131649148769965723:s->NDArray___sub__-9558798608273926456\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-7786309113067083429:s->TupleValue___add__-15259460202689358531\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-12579319251068649370:s->concat-430064524623572644\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-17067340853146132798:s->assume_shape-8316602628326787375\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-4148863126349750477:s->TupleInt_length-11379923615081194535\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-4148863126349750477:s->possible_values-13042725723116283049\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-13770179520251441998:s->Value_int-1870696621799859130\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-14757501459592564217:s->TupleValue___getitem__-14448359888109329694\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-14448359888109329694:s->Int___sub__-11477953740632672431\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-14448359888109329694:s->possible_values-12211324669098738792\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-2598150418935018079:s->Value_float-15173113486080567242\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-12107377412216353484:s->Value_float-6235596405652351031\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-3712217405396014230:s->sum-1955564354691009820\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_int-12938778466233897741:s->Int___init__-5871781006564002453\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-10864543514592368202:s->NDArray_vector-467762655970733886\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-10864543514592368202:s->TupleInt___init__-12938778466233897741\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-15769018209198649053:s->asarray-17776165865978447989\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-6690955771313385503:s->sum-1681433789052220133\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-16788298149597563309:s->NDArray_vector-18083105675662741245\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_dtype-15121139857639374588\n", - "\n", - "\n", - "NDArray_dtype\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_isfinite-10080759905092916392\n", - "\n", - "\n", - "assume_isfinite\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_dtype-10080759905092916392\n", - "\n", - "\n", - "NDArray_dtype\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_shape-14591484260056516843\n", - "\n", - "\n", - "assume_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_dtype-11743562013128004906\n", - "\n", - "\n", - "NDArray_dtype\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_dtype-3429551472952562336\n", - "\n", - "\n", - "assume_dtype(NDArray_var("X"), ·)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "DType_float64-0\n", - "\n", - "\n", - "DType_float64\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_device-15121139857639374588\n", - "\n", - "\n", - "NDArray_device\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "asarray-9510298863856844727\n", - "\n", - "\n", - "asarray(·, OptionalDType_none, OptionalBool_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float___truediv__-12808993487988576005\n", - "\n", - "\n", - "Float___truediv__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float_rational-0\n", - "\n", - "\n", - "Float_rational((rational 1 1))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float_from_int-11951456526892775522\n", - "\n", - "\n", - "Float_from_int\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float_rational-17615343019692007359\n", - "\n", - "\n", - "Float_rational((rational 1 999998))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float_from_int-12938778466233897741\n", - "\n", - "\n", - "Float_from_int\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt_length-11379923615081194535\n", - "\n", - "\n", - "TupleInt_length\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float___truediv__-5949890542083451333\n", - "\n", - "\n", - "Float___truediv__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float___init__-10858178701590265856\n", - "\n", - "\n", - "Float___init__(1.0)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float___init__-15726603433882419200\n", - "\n", - "\n", - "Float___init__(1000000.0)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float_rational-5871781006564002453\n", - "\n", - "\n", - "Float_rational((rational 1000000 1))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___sub__-2601583573127157282\n", - "\n", - "\n", - "Int___sub__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Float_rational-11743562013128004906\n", - "\n", - "\n", - "Float_rational((rational 999998 1))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-11068081844434038611\n", - "\n", - "\n", - "IndexKey_multi_axis\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-7546443524583315781\n", - "\n", - "\n", - "MultiAxisIndexKey___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-2961965818023366657\n", - "\n", - "\n", - "IndexKey_multi_axis\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-9019874688858188702\n", - "\n", - "\n", - "MultiAxisIndexKey___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_slice-4520820669176069863\n", - "\n", - "\n", - "IndexKey_slice\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Slice___init__-15501507093852132239\n", - "\n", - "\n", - "Slice___init__(OptionalInt_none, ·, OptionalInt_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-2650124047376210733\n", - "\n", - "\n", - "IndexKey_multi_axis\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-4155431249018709085\n", - "\n", - "\n", - "MultiAxisIndexKey___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-7690503999922668929\n", - "\n", - "\n", - "ndarray_index\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-17968234112188297122\n", - "\n", - "\n", - "NDArray___eq__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-3689419615158525606\n", - "\n", - "\n", - "IndexKey_multi_axis\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-10696952293987308628\n", - "\n", - "\n", - "MultiAxisIndexKey___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-10236680790416494354\n", - "\n", - "\n", - "ndarray_index\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-7887474207095380730\n", - "\n", - "\n", - "NDArray___eq__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-4468847040734877209\n", - "\n", - "\n", - "ndarray_index\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-3677844317228415595\n", - "\n", - "\n", - "NDArray___eq__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_int-12938778466233897741\n", - "\n", - "\n", - "IndexKey_int\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___sub__-11477953740632672431\n", - "\n", - "\n", - "Int___sub__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-9457253364840142751\n", - "\n", - "\n", - "ndarray_index\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-5948126446311695931\n", - "\n", - "\n", - "NDArray___eq__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray_index-1091269196223507527\n", - "\n", - "\n", - "ndarray_index\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___eq__-14314110614928331155\n", - "\n", - "\n", - "NDArray___eq__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "IndexKey_multi_axis-5456168980075999428\n", - "\n", - "\n", - "IndexKey_multi_axis\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___add__-8188473634840644445\n", - "\n", - "\n", - "MultiAxisIndexKey___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-16347205588787662656\n", - "\n", - "\n", - "Int___init__(1000000)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-11743562013128004906\n", - "\n", - "\n", - "Int___init__(2)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-4603643575659657750\n", - "\n", - "\n", - "Int___init__(999998)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-7742477628363861583\n", - "\n", - "\n", - "NDArray_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue_length-51973628441192654\n", - "\n", - "\n", - "TupleValue_length\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___init__-14757501459592564217\n", - "\n", - "\n", - "TupleValue___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue_length-883374682458736911\n", - "\n", - "\n", - "TupleValue_length\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___init__-3845340500482103568\n", - "\n", - "\n", - "TupleValue___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___add__-17495654355659155035\n", - "\n", - "\n", - "Int___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-5871781006564002453\n", - "\n", - "\n", - "Int___init__(1)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_to_int-7118971088111087942\n", - "\n", - "\n", - "Value_to_int\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_to_value-1247190081547085489\n", - "\n", - "\n", - "NDArray_to_value\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_to_int-5352221723193614120\n", - "\n", - "\n", - "Value_to_int\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_to_value-17927184790339163283\n", - "\n", - "\n", - "NDArray_to_value\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue_length-467762655970733886\n", - "\n", - "\n", - "TupleValue_length\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___add__-15259460202689358531\n", - "\n", - "\n", - "TupleValue___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue_length-18083105675662741245\n", - "\n", - "\n", - "TupleValue_length\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "possible_values-12211324669098738792\n", - "\n", - "\n", - "possible_values\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___getitem__-14078601210367663714\n", - "\n", - "\n", - "TupleInt___getitem__(·, Int___init__(0))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-12782857580910319779\n", - "\n", - "\n", - "NDArray_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___getitem__-11605336705429392564\n", - "\n", - "\n", - "TupleInt___getitem__(·, Int___init__(0))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-10080759905092916392\n", - "\n", - "\n", - "NDArray_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___getitem__-12686509587440430679\n", - "\n", - "\n", - "TupleInt___getitem__(·, Int___init__(0))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___init__-103947256882385308\n", - "\n", - "\n", - "TupleInt___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___getitem__-7967890718712059612\n", - "\n", - "\n", - "TupleInt___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___add__-13243224121832505654\n", - "\n", - "\n", - "TupleInt___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int___init__-6755155689022739364\n", - "\n", - "\n", - "Int___init__(20)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-9353306107957757443\n", - "\n", - "\n", - "MultiAxisIndexKey___init__(MultiAxisIndexKeyItem_slice(Slice___init__(OptionalInt_none, OptionalInt_none, OptionalInt_none)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-12159351040657546138\n", - "\n", - "\n", - "MultiAxisIndexKey___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-9665147878604913367\n", - "\n", - "\n", - "MultiAxisIndexKey___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_slice-6287570034093543685\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_slice\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-17771263905015585321\n", - "\n", - "\n", - "MultiAxisIndexKey___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_int-12938778466233897741\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_int\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-4312926155411299247\n", - "\n", - "\n", - "MultiAxisIndexKey___init__(MultiAxisIndexKeyItem_int(Int___init__(0)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKey___init__-10392601675740072316\n", - "\n", - "\n", - "MultiAxisIndexKey___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_slice-4520820669176069863\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_slice\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_slice-3793366872040910914\n", - "\n", - "\n", - "MultiAxisIndexKeyItem_slice\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Slice___init__-14445438978175812750\n", - "\n", - "\n", - "Slice___init__(OptionalInt_none, ·, OptionalInt_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Slice___init__-1162291712589082458\n", - "\n", - "\n", - "Slice___init__(OptionalInt_none, ·, OptionalInt_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-11120055472875231265\n", - "\n", - "\n", - "NDArray_scalar\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_float-5248274466311228812\n", - "\n", - "\n", - "Value_float\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "asarray-7902703286805427734\n", - "\n", - "\n", - "asarray(·, OptionalDType_none, OptionalBool_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-17483047916985507424\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-18325169333216085054\n", - "\n", - "\n", - "NDArray___setitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "mean-9206860573968271485\n", - "\n", - "\n", - "mean(·, ·, FALSE)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-16307929054953181812\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalIntOrTuple_some-6859102945905124672\n", - "\n", - "\n", - "OptionalIntOrTuple_some(IntOrTuple_int(Int___init__(0)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "concat-9071020324919791953\n", - "\n", - "\n", - "concat(·, OptionalInt_some(Int___init__(0)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___add__-17612194977553982959\n", - "\n", - "\n", - "TupleNDArray___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-18135092377765138894\n", - "\n", - "\n", - "TupleNDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "svd-7253966389981509278\n", - "\n", - "\n", - "svd(·, FALSE)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_T-2858018561140981349\n", - "\n", - "\n", - "NDArray_T\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-11279504549742320031\n", - "\n", - "\n", - "NDArray___truediv__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-18178625676753040942\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-11026489642259430172\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-7132500556515696557\n", - "\n", - "\n", - "NDArray___matmul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-15656725660214344740\n", - "\n", - "\n", - "NDArray___truediv__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "astype-6261542238027864055\n", - "\n", - "\n", - "astype\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-2598150418935018079\n", - "\n", - "\n", - "NDArray_scalar\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-9557034512502171054\n", - "\n", - "\n", - "NDArray___matmul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-9788377807842481490\n", - "\n", - "\n", - "NDArray___truediv__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-5767087113385015795\n", - "\n", - "\n", - "NDArray___setitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_T-10444575304181264970\n", - "\n", - "\n", - "NDArray_T\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-7696624279617524538\n", - "\n", - "\n", - "NDArray___mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-9914932780259612220\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-14757501459592564217\n", - "\n", - "\n", - "NDArray_scalar\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-9658389681233211557\n", - "\n", - "\n", - "TupleValue___getitem__(·, Int___init__(0))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-16424482750509214731\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "concat-430064524623572644\n", - "\n", - "\n", - "concat(·, OptionalInt_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___truediv__-3215265837560371319\n", - "\n", - "\n", - "NDArray___truediv__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-11494903289568215254\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-1818913068061409678\n", - "\n", - "\n", - "TupleNDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-2205987174022554874\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___gt__-15651908559655936539\n", - "\n", - "\n", - "NDArray___gt__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-1143242824664700181\n", - "\n", - "\n", - "NDArray_scalar(Value_float(Float___init__(0.0001)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___gt__-8664676620264668937\n", - "\n", - "\n", - "NDArray___gt__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-17539377729349800285\n", - "\n", - "\n", - "TupleNDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-8440009558605893705\n", - "\n", - "\n", - "NDArray___mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "asarray-17776165865978447989\n", - "\n", - "\n", - "asarray(·, OptionalDType_none, OptionalBool_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-3845340500482103568\n", - "\n", - "\n", - "NDArray_scalar\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "sum-1955564354691009820\n", - "\n", - "\n", - "sum(·, OptionalIntOrTuple_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "astype-14592420363448682842\n", - "\n", - "\n", - "astype(·, DType_int32)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-13476223401931994896\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_T-15484955256727723166\n", - "\n", - "\n", - "NDArray_T\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-15121139857639374588\n", - "\n", - "\n", - "NDArray_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___setitem__-7453141863274628760\n", - "\n", - "\n", - "NDArray___setitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "mean-3476503888447580293\n", - "\n", - "\n", - "mean(·, ·, FALSE)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-10680274783444675613\n", - "\n", - "\n", - "TupleNDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "astype-12468708834165933853\n", - "\n", - "\n", - "astype(·, DType_int32)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-15588902513610108474\n", - "\n", - "\n", - "NDArray_scalar\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-1182067134106770624\n", - "\n", - "\n", - "NDArray_index(·, TupleInt___init__(Int___init__(0)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-17758114586016463110\n", - "\n", - "\n", - "NDArray___getitem__(·, IndexKey_int(Int___init__(0)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_float-15173113486080567242\n", - "\n", - "\n", - "Value_float\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-3836913244690017957\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-10045558824545728354\n", - "\n", - "\n", - "TupleNDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-6343722845416298339\n", - "\n", - "\n", - "NDArray___getitem__(·, IndexKey_int(Int___init__(0)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-12107377412216353484\n", - "\n", - "\n", - "NDArray_scalar\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_float-6235596405652351031\n", - "\n", - "\n", - "Value_float\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "sum-1681433789052220133\n", - "\n", - "\n", - "sum(·, OptionalIntOrTuple_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-13392291772433010205\n", - "\n", - "\n", - "NDArray___matmul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-15957548086918070248\n", - "\n", - "\n", - "TupleNDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "reshape-4112525690760736104\n", - "\n", - "\n", - "reshape(·, TupleInt___init__(Int___init__(-1)), OptionalBool_none)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_value_one_of-5323778840018127892\n", - "\n", - "\n", - "assume_value_one_of\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "assume_shape-8316602628326787375\n", - "\n", - "\n", - "assume_shape(assume_dtype(NDArray_var("y"), DType_int64), ·)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "std-4851945112178408602\n", - "\n", - "\n", - "std\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "svd-2189404700831293460\n", - "\n", - "\n", - "svd(·, FALSE)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "unique_counts-7742477628363861583\n", - "\n", - "\n", - "unique_counts\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-8455018010728142919\n", - "\n", - "\n", - "NDArray___mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray-sqrt-4416873412293684555\n", - "\n", - "\n", - "ndarray-sqrt\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "zeros-16505489609336576318\n", - "\n", - "\n", - "zeros\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___add__-10752996994297486686\n", - "\n", - "\n", - "TupleInt___add__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalDType_some-3429551472952562336\n", - "\n", - "\n", - "OptionalDType_some\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalDevice_some-5144327209428843504\n", - "\n", - "\n", - "OptionalDevice_some\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_scalar-13770179520251441998\n", - "\n", - "\n", - "NDArray_scalar\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_int-1870696621799859130\n", - "\n", - "\n", - "Value_int\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___getitem__-9812641508136405718\n", - "\n", - "\n", - "NDArray___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-4099386548708531027\n", - "\n", - "\n", - "NDArray___mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_T-17147757364762811680\n", - "\n", - "\n", - "NDArray_T\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-1374586120005010617\n", - "\n", - "\n", - "NDArray___sub__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-8877293197236476153\n", - "\n", - "\n", - "NDArray___sub__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-9558798608273926456\n", - "\n", - "\n", - "NDArray___sub__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___matmul__-10968585808826125111\n", - "\n", - "\n", - "NDArray___matmul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "unique_inverse-7742477628363861583\n", - "\n", - "\n", - "unique_inverse\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "ndarray-sqrt-5404195351634806774\n", - "\n", - "\n", - "ndarray-sqrt\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___mul__-3756686807776082277\n", - "\n", - "\n", - "NDArray___mul__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray___sub__-10430407918099810154\n", - "\n", - "\n", - "NDArray___sub__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___init__-12782857580910319779\n", - "\n", - "\n", - "TupleNDArray___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___getitem__-13683004811263061306\n", - "\n", - "\n", - "TupleNDArray___getitem__(·, Int___init__(0))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "unique_values-12782857580910319779\n", - "\n", - "\n", - "unique_values\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_vector-18083105675662741245\n", - "\n", - "\n", - "NDArray_vector\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "unique_values-7742477628363861583\n", - "\n", - "\n", - "unique_values\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_vector-467762655970733886\n", - "\n", - "\n", - "NDArray_vector\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "possible_values-13042725723116283049\n", - "\n", - "\n", - "possible_values\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-1353837537593392198\n", - "\n", - "\n", - "TupleValue___getitem__(·, Int___init__(0))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___init__-1870696621799859130\n", - "\n", - "\n", - "TupleInt___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalInt_some-11224002729757616573\n", - "\n", - "\n", - "OptionalInt_some\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalInt_some-12938778466233897741\n", - "\n", - "\n", - "OptionalInt_some\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "OptionalInt_some-12990752094675090395\n", - "\n", - "\n", - "OptionalInt_some\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-7586556743040283621-value\n", - "\n", - "\n", - "(py-object -9223372036570011657 0)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-7586556743040283621\n", - "\n", - "\n", - "Int_to_py(Int___init__(0))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-11951456526892775522\n", - "\n", - "\n", - "Int_to_py\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-11951456526892775522-value\n", - "\n", - "\n", - "(py-object -9223372036570011657 999998)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-6079675520328773069\n", - "\n", - "\n", - "Int_to_py\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-6079675520328773069-value\n", - "\n", - "\n", - "(py-object -9223372036570011657 2)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-103947256882385308\n", - "\n", - "\n", - "Int_to_py\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-103947256882385308-value\n", - "\n", - "\n", - "(py-object -9223372036570011657 20)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-5092353580987650850-value\n", - "\n", - "\n", - "(py-object -9223372036570011657 -2)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-5092353580987650850\n", - "\n", - "\n", - "Int_to_py(Int___init__(-1))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-1870696621799859130\n", - "\n", - "\n", - "Int_to_py\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-1870696621799859130-value\n", - "\n", - "\n", - "(py-object -9223372036570011657 1000000)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Boolean_to_py-155920885323577962-value\n", - "\n", - "\n", - "(py-object 284764003 0)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Boolean_to_py-155920885323577962\n", - "\n", - "\n", - "Boolean_to_py(FALSE)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-12938778466233897741\n", - "\n", - "\n", - "Int_to_py\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Int_to_py-12938778466233897741-value\n", - "\n", - "\n", - "(py-object -9223372036570011657 1)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_shape-1714775736476281168\n", - "\n", - "\n", - "NDArray_shape\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___init__-6079675520328773069\n", - "\n", - "\n", - "TupleInt___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleInt___init__-12938778466233897741\n", - "\n", - "\n", - "TupleInt___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___init__-14497633317386600947\n", - "\n", - "\n", - "TupleNDArray___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleNDArray___init__-6131649148769965723\n", - "\n", - "\n", - "TupleNDArray___init__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-7786309113067083429\n", - "\n", - "\n", - "TupleValue___getitem__(·, Int___init__(0))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-12579319251068649370\n", - "\n", - "\n", - "NDArray_index(·, ALL_INDICES)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-17067340853146132798\n", - "\n", - "\n", - "NDArray_index(·, ALL_INDICES)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-4148863126349750477\n", - "\n", - "\n", - "TupleValue___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-1143242824664700181-value\n", - "\n", - "\n", - "()\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-1143242824664700181\n", - "\n", - "\n", - "greater_zero(Value_float(Float___init__(0.0001)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-13770179520251441998\n", - "\n", - "\n", - "greater_zero\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-13770179520251441998-value\n", - "\n", - "\n", - "()\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-14757501459592564217\n", - "\n", - "\n", - "greater_zero\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "TupleValue___getitem__-14448359888109329694\n", - "\n", - "\n", - "TupleValue___getitem__\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-14757501459592564217-value\n", - "\n", - "\n", - "()\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-2598150418935018079\n", - "\n", - "\n", - "greater_zero\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-2598150418935018079-value\n", - "\n", - "\n", - "()\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-12107377412216353484\n", - "\n", - "\n", - "greater_zero\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "greater_zero-12107377412216353484-value\n", - "\n", - "\n", - "()\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-3712217405396014230\n", - "\n", - "\n", - "NDArray_index(·, TupleInt_EMPTY)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_int-12938778466233897741\n", - "\n", - "\n", - "Value_int\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-10864543514592368202\n", - "\n", - "\n", - "NDArray_index\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-15769018209198649053\n", - "\n", - "\n", - "NDArray_index(·, ALL_INDICES)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-5822399466274154604\n", - "\n", - "\n", - "NDArray_index(assume_dtype(NDArray_var("y"), DType_int64), ALL_INDICES)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-7547271516962905184\n", - "\n", - "\n", - "NDArray_index(NDArray_var("y"), ALL_INDICES)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-6690955771313385503\n", - "\n", - "\n", - "NDArray_index(·, TupleInt_EMPTY)\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "NDArray_index-16788298149597563309\n", - "\n", - "\n", - "NDArray_index(·, TupleInt___init__(Int___init__(0)))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "Value_int-7586556743040283621\n", - "\n", - "\n", - "Value_int(Int___init__(0))\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{X}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}isfinite}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{y}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int64}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}value\\PYZus{}one\\PYZus{}of}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{=} \\PY{n}{asarray}\\PY{p}{(}\\PY{n}{reshape}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{)}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{=} \\PY{n}{astype}\\PY{p}{(}\\PY{n}{unique\\PYZus{}counts}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{dtype}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1000000.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{=} \\PY{n}{zeros}\\PY{p}{(}\n", + " \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,}\n", + " \\PY{n}{OptionalDType}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{dtype}\\PY{p}{)}\\PY{p}{,}\n", + " \\PY{n}{OptionalDevice}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{device}\\PY{p}{)}\\PY{p}{,}\n", + "\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1} \\PY{o}{=} \\PY{n}{OptionalIntOrTuple}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{IntOrTuple}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]} \\PY{o}{=} \\PY{n}{mean}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]} \\PY{o}{=} \\PY{n}{mean}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}6} \\PY{o}{=} \\PY{n}{unique\\PYZus{}values}\\PY{p}{(}\\PY{n}{concat}\\PY{p}{(}\\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{unique\\PYZus{}values}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{=} \\PY{n}{concat}\\PY{p}{(}\n", + " \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{==} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]}\\PY{p}{)}\n", + " \\PY{o}{+} \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{==} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,}\n", + " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,}\n", + "\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}8} \\PY{o}{=} \\PY{n}{std}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{std}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\n", + " \\PY{n}{sqrt}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)} \\PY{o}{/} \\PY{n}{Float}\\PY{o}{.}\\PY{n}{from\\PYZus{}int}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{p}{)}\\PY{p}{,} \\PY{n}{FALSE}\n", + "\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}Slice\\PYZus{}1} \\PY{o}{=} \\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}int}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}9} \\PY{o}{=} \\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{/} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\n", + " \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\n", + "\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{]}\n", + "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\n", + " \\PY{p}{(}\n", + " \\PY{n}{sqrt}\\PY{p}{(}\n", + " \\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\n", + " \\PY{o}{*} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)} \\PY{o}{/} \\PY{n}{Float}\\PY{o}{.}\\PY{n}{from\\PYZus{}int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T}\n", + " \\PY{p}{)}\\PY{o}{.}\\PY{n}{T}\n", + " \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}9}\\PY{p}{,}\n", + " \\PY{n}{FALSE}\\PY{p}{,}\n", + "\\PY{p}{)}\n", + "\\PY{p}{(}\n", + " \\PY{p}{(}\\PY{n}{asarray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{)}\\PY{p}{)}\n", + " \\PY{o}{@} \\PY{p}{(}\n", + " \\PY{n}{\\PYZus{}NDArray\\PYZus{}9}\n", + " \\PY{o}{@} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{o}{.}\\PY{n}{T}\\PY{p}{[}\n", + " \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\n", + " \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\n", + " \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\n", + " \\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\n", + " \\PY{n}{Slice}\\PY{p}{(}\n", + " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,}\n", + " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\n", + " \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\n", + " \\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\n", + " \\PY{o}{.}\\PY{n}{to\\PYZus{}int}\n", + " \\PY{p}{)}\\PY{p}{,}\n", + " \\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{p}{]}\n", + " \\PY{p}{)}\n", + "\\PY{p}{)}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", + "\\end{Verbatim}\n" ], - "source": [ - "egraph.display(n_inline_leaves=3, split_primitive_outputs=True)" - ] - }, - { - "cell_type": "markdown", - "id": "21e4ee3a", - "metadata": {}, - "source": [ - "## Translating for Numba\n", - "\n", - "We are getting closer to a form we could translate back to Numba, but we have to make a few changes. Numba doesn't\n", - "support the `axis` keyword for `mean` or `std`, but it does support it for `sum`, so we have to translate all forms\n", - "from one to the other, with a rule like this (defined in [`egglog.exp.array_api_numba`](https://github.com/egraphs-good/egglog-python/blob/main/python/egglog/exp/array_api_numba.py)):\n", - "\n", - "```python\n", - "axis = OptionalIntOrTuple.some(IntOrTuple.int(i))\n", - "rewrite(std(x, axis)).to(sqrt(mean(square(abs(x - mean(x, axis, keepdims=TRUE))), axis)))\n", - "```\n", - "\n", - "We can run those additional rewrites now to get a new extracted version\n" + "text/plain": [ + "_NDArray_1 = NDArray.var(\"X\")\n", + "assume_dtype(_NDArray_1, DType.float64)\n", + "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n", + "assume_isfinite(_NDArray_1)\n", + "_NDArray_2 = NDArray.var(\"y\")\n", + "assume_dtype(_NDArray_2, DType.int64)\n", + "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n", + "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n", + "_NDArray_3 = asarray(reshape(asarray(_NDArray_2), TupleInt(Int(-1))))\n", + "_NDArray_4 = astype(unique_counts(_NDArray_3)[Int(1)], asarray(_NDArray_1).dtype) / NDArray.scalar(Value.float(Float(1000000.0)))\n", + "_NDArray_5 = zeros(\n", + " TupleInt(unique_inverse(_NDArray_3)[Int(0)].shape[Int(0)]) + TupleInt(asarray(_NDArray_1).shape[Int(1)]),\n", + " OptionalDType.some(asarray(_NDArray_1).dtype),\n", + " OptionalDevice.some(asarray(_NDArray_1).device),\n", + ")\n", + "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n", + "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n", + "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n", + "_NDArray_5[_IndexKey_1] = mean(asarray(_NDArray_1)[ndarray_index(unique_inverse(_NDArray_3)[Int(1)] == NDArray.scalar(Value.int(Int(0))))], _OptionalIntOrTuple_1)\n", + "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n", + "_NDArray_5[_IndexKey_2] = mean(asarray(_NDArray_1)[ndarray_index(unique_inverse(_NDArray_3)[Int(1)] == NDArray.scalar(Value.int(Int(1))))], _OptionalIntOrTuple_1)\n", + "_NDArray_6 = unique_values(concat(TupleNDArray(unique_values(asarray(_NDArray_3)))))\n", + "_NDArray_7 = concat(\n", + " TupleNDArray(asarray(_NDArray_1)[ndarray_index(_NDArray_3 == _NDArray_6[IndexKey.int(Int(0))])] - _NDArray_5[_IndexKey_1])\n", + " + TupleNDArray(asarray(_NDArray_1)[ndarray_index(_NDArray_3 == _NDArray_6[IndexKey.int(Int(1))])] - _NDArray_5[_IndexKey_2]),\n", + " OptionalInt.some(Int(0)),\n", + ")\n", + "_NDArray_8 = std(_NDArray_7, _OptionalIntOrTuple_1)\n", + "_NDArray_8[ndarray_index(std(_NDArray_7, _OptionalIntOrTuple_1) == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n", + "_TupleNDArray_1 = svd(\n", + " sqrt(asarray(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(asarray(_NDArray_1).shape[Int(0)] - _NDArray_6.shape[Int(0)]))))) * (_NDArray_7 / _NDArray_8), FALSE\n", + ")\n", + "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n", + "_NDArray_9 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_8).T / _TupleNDArray_1[\n", + " Int(1)\n", + "][IndexKey.slice(_Slice_1)]\n", + "_TupleNDArray_2 = svd(\n", + " (\n", + " sqrt(\n", + " (NDArray.scalar(Value.int(asarray(_NDArray_1).shape[Int(0)])) * _NDArray_4)\n", + " * NDArray.scalar(Value.float(Float(1.0) / Float.from_int(_NDArray_6.shape[Int(0)] - Int(1))))\n", + " )\n", + " * (_NDArray_5 - (_NDArray_4 @ _NDArray_5)).T\n", + " ).T\n", + " @ _NDArray_9,\n", + " FALSE,\n", + ")\n", + "(\n", + " (asarray(_NDArray_1) - (_NDArray_4 @ _NDArray_5))\n", + " @ (\n", + " _NDArray_9\n", + " @ _TupleNDArray_2[Int(2)].T[\n", + " IndexKey.multi_axis(\n", + " _MultiAxisIndexKey_1\n", + " + MultiAxisIndexKey(\n", + " MultiAxisIndexKeyItem.slice(\n", + " Slice(\n", + " OptionalInt.none,\n", + " OptionalInt.some(\n", + " sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n", + " .to_value()\n", + " .to_int\n", + " ),\n", + " )\n", + " )\n", + " )\n", + " )\n", + " ]\n", + " )\n", + ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(_NDArray_6.shape[Int(0)] - Int(1))))))]" ] - }, + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from egglog import EGraph\n", + "from egglog.exp.array_api import array_api_module\n", + "\n", + "with EGraph([array_api_module]) as egraph:\n", + " X_r2 = run_lda(X_arr, y_arr)\n", + " egraph.display(n_inline_leaves=3, split_primitive_outputs=True)\n", + "X_r2" + ] + }, + { + "cell_type": "markdown", + "id": "580da17b", + "metadata": {}, + "source": [ + "We now have extracted out a program which is semantically equivalent to the original call! One thing you might notice\n", + "is that the expression has more types than customary NumPy code. Every object is lifted into a strongly typed `egglog`\n", + "class. This is so that when we run optimizations, we know the types of all the objects. It still is compatible with\n", + "normal Python objects, but they are [converted](type-promotion) when they are passed as argument.\n", + "\n", + "## Optimizing our result\n", + "\n", + "Now that we have the an expression, we can run our rewrite rules to \"optimize\" it, extracting out the lowest cost\n", + "(smallest) expression afterword:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "4d3cd4f3", + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 6, - "id": "9e79f88e", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
_NDArray_1 = NDArray.var("X")\n",
-              "assume_dtype(_NDArray_1, DType.float64)\n",
-              "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n",
-              "assume_isfinite(_NDArray_1)\n",
-              "_NDArray_2 = NDArray.var("y")\n",
-              "assume_dtype(_NDArray_2, DType.int64)\n",
-              "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n",
-              "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n",
-              "_NDArray_3 = astype(\n",
-              "    NDArray.vector(TupleValue(sum(_NDArray_2 == NDArray.scalar(Value.int(Int(0)))).to_value()) + TupleValue(sum(_NDArray_2 == NDArray.scalar(Value.int(Int(1)))).to_value())),\n",
-              "    DType.float64,\n",
-              ") / NDArray.scalar(Value.float(Float(1000000.0)))\n",
-              "_NDArray_4 = zeros(TupleInt(Int(2)) + TupleInt(Int(20)), OptionalDType.some(DType.float64), OptionalDevice.some(_NDArray_1.device))\n",
-              "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n",
-              "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n",
-              "_NDArray_5 = _NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(0))))]\n",
-              "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n",
-              "_NDArray_4[_IndexKey_1] = sum(_NDArray_5, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_5.shape[Int(0)]))\n",
-              "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n",
-              "_NDArray_6 = _NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(1))))]\n",
-              "_NDArray_4[_IndexKey_2] = sum(_NDArray_6, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_6.shape[Int(0)]))\n",
-              "_NDArray_7 = concat(TupleNDArray(_NDArray_5 - _NDArray_4[_IndexKey_1]) + TupleNDArray(_NDArray_6 - _NDArray_4[_IndexKey_2]), OptionalInt.some(Int(0)))\n",
-              "_NDArray_8 = square(_NDArray_7 - expand_dims(sum(_NDArray_7, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_7.shape[Int(0)]))))\n",
-              "_NDArray_9 = sqrt(sum(_NDArray_8, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_8.shape[Int(0)])))\n",
-              "_NDArray_10 = copy(_NDArray_9)\n",
-              "_NDArray_10[ndarray_index(_NDArray_9 == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n",
-              "_TupleNDArray_1 = svd(sqrt(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(Int(999998))))) * (_NDArray_7 / _NDArray_10), FALSE)\n",
-              "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n",
-              "_NDArray_11 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_10).T / _TupleNDArray_1[\n",
-              "    Int(1)\n",
-              "][IndexKey.slice(_Slice_1)]\n",
-              "_TupleNDArray_2 = svd(\n",
-              "    (sqrt((NDArray.scalar(Value.int(Int(1000000))) * _NDArray_3) * NDArray.scalar(Value.float(Float(1.0)))) * (_NDArray_4 - (_NDArray_3 @ _NDArray_4)).T).T @ _NDArray_11, FALSE\n",
-              ")\n",
-              "(\n",
-              "    (_NDArray_1 - (_NDArray_3 @ _NDArray_4))\n",
-              "    @ (\n",
-              "        _NDArray_11\n",
-              "        @ _TupleNDArray_2[Int(2)].T[\n",
-              "            IndexKey.multi_axis(\n",
-              "                _MultiAxisIndexKey_1\n",
-              "                + MultiAxisIndexKey(\n",
-              "                    MultiAxisIndexKeyItem.slice(\n",
-              "                        Slice(\n",
-              "                            OptionalInt.none,\n",
-              "                            OptionalInt.some(\n",
-              "                                sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n",
-              "                                .to_value()\n",
-              "                                .to_int\n",
-              "                            ),\n",
-              "                        )\n",
-              "                    )\n",
-              "                )\n",
-              "            )\n",
-              "        ]\n",
-              "    )\n",
-              ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(Int(1))))))]\n",
-              "
\n" - ], - "text/latex": [ - "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{X}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}isfinite}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{y}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int64}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{assume\\PYZus{}value\\PYZus{}one\\PYZus{}of}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{=} \\PY{n}{astype}\\PY{p}{(}\n", - " \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{vector}\\PY{p}{(}\\PY{n}{TupleValue}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,}\n", - " \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{,}\n", - "\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1000000.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{=} \\PY{n}{zeros}\\PY{p}{(}\\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalDType}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalDevice}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{o}{.}\\PY{n}{device}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{=} \\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", - "\\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1} \\PY{o}{=} \\PY{n}{OptionalIntOrTuple}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{IntOrTuple}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]} \\PY{o}{=} \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}6} \\PY{o}{=} \\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]} \\PY{o}{=} \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{=} \\PY{n}{concat}\\PY{p}{(}\\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}8} \\PY{o}{=} \\PY{n}{square}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{\\PYZhy{}} \\PY{n}{expand\\PYZus{}dims}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}9} \\PY{o}{=} \\PY{n}{sqrt}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}10} \\PY{o}{=} \\PY{n}{copy}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}9}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}10}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}9} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\\PY{n}{sqrt}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)} \\PY{o}{/} \\PY{n}{Float}\\PY{o}{.}\\PY{n}{from\\PYZus{}int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{999998}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}10}\\PY{p}{)}\\PY{p}{,} \\PY{n}{FALSE}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}Slice\\PYZus{}1} \\PY{o}{=} \\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}int}\\PY{p}{)}\\PY{p}{)}\n", - "\\PY{n}{\\PYZus{}NDArray\\PYZus{}11} \\PY{o}{=} \\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}10}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{/} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\n", - " \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\n", - "\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{]}\n", - "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\n", - " \\PY{p}{(}\\PY{n}{sqrt}\\PY{p}{(}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)} \\PY{o}{*} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}11}\\PY{p}{,} \\PY{n}{FALSE}\n", - "\\PY{p}{)}\n", - "\\PY{p}{(}\n", - " \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\\PY{p}{)}\n", - " \\PY{o}{@} \\PY{p}{(}\n", - " \\PY{n}{\\PYZus{}NDArray\\PYZus{}11}\n", - " \\PY{o}{@} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{o}{.}\\PY{n}{T}\\PY{p}{[}\n", - " \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\n", - " \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\n", - " \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\n", - " \\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\n", - " \\PY{n}{Slice}\\PY{p}{(}\n", - " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,}\n", - " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\n", - " \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\n", - " \\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\n", - " \\PY{o}{.}\\PY{n}{to\\PYZus{}int}\n", - " \\PY{p}{)}\\PY{p}{,}\n", - " \\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{p}{)}\n", - " \\PY{p}{]}\n", - " \\PY{p}{)}\n", - "\\PY{p}{)}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", - "\\end{Verbatim}\n" - ], - "text/plain": [ - "_NDArray_1 = NDArray.var(\"X\")\n", - "assume_dtype(_NDArray_1, DType.float64)\n", - "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n", - "assume_isfinite(_NDArray_1)\n", - "_NDArray_2 = NDArray.var(\"y\")\n", - "assume_dtype(_NDArray_2, DType.int64)\n", - "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n", - "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n", - "_NDArray_3 = astype(\n", - " NDArray.vector(TupleValue(sum(_NDArray_2 == NDArray.scalar(Value.int(Int(0)))).to_value()) + TupleValue(sum(_NDArray_2 == NDArray.scalar(Value.int(Int(1)))).to_value())),\n", - " DType.float64,\n", - ") / NDArray.scalar(Value.float(Float(1000000.0)))\n", - "_NDArray_4 = zeros(TupleInt(Int(2)) + TupleInt(Int(20)), OptionalDType.some(DType.float64), OptionalDevice.some(_NDArray_1.device))\n", - "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n", - "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n", - "_NDArray_5 = _NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(0))))]\n", - "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n", - "_NDArray_4[_IndexKey_1] = sum(_NDArray_5, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_5.shape[Int(0)]))\n", - "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n", - "_NDArray_6 = _NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(1))))]\n", - "_NDArray_4[_IndexKey_2] = sum(_NDArray_6, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_6.shape[Int(0)]))\n", - "_NDArray_7 = concat(TupleNDArray(_NDArray_5 - _NDArray_4[_IndexKey_1]) + TupleNDArray(_NDArray_6 - _NDArray_4[_IndexKey_2]), OptionalInt.some(Int(0)))\n", - "_NDArray_8 = square(_NDArray_7 - expand_dims(sum(_NDArray_7, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_7.shape[Int(0)]))))\n", - "_NDArray_9 = sqrt(sum(_NDArray_8, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_8.shape[Int(0)])))\n", - "_NDArray_10 = copy(_NDArray_9)\n", - "_NDArray_10[ndarray_index(_NDArray_9 == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n", - "_TupleNDArray_1 = svd(sqrt(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(Int(999998))))) * (_NDArray_7 / _NDArray_10), FALSE)\n", - "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n", - "_NDArray_11 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_10).T / _TupleNDArray_1[\n", - " Int(1)\n", - "][IndexKey.slice(_Slice_1)]\n", - "_TupleNDArray_2 = svd(\n", - " (sqrt((NDArray.scalar(Value.int(Int(1000000))) * _NDArray_3) * NDArray.scalar(Value.float(Float(1.0)))) * (_NDArray_4 - (_NDArray_3 @ _NDArray_4)).T).T @ _NDArray_11, FALSE\n", - ")\n", - "(\n", - " (_NDArray_1 - (_NDArray_3 @ _NDArray_4))\n", - " @ (\n", - " _NDArray_11\n", - " @ _TupleNDArray_2[Int(2)].T[\n", - " IndexKey.multi_axis(\n", - " _MultiAxisIndexKey_1\n", - " + MultiAxisIndexKey(\n", - " MultiAxisIndexKeyItem.slice(\n", - " Slice(\n", - " OptionalInt.none,\n", - " OptionalInt.some(\n", - " sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n", - " .to_value()\n", - " .to_int\n", - " ),\n", - " )\n", - " )\n", - " )\n", - " )\n", - " ]\n", - " )\n", - ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(Int(1))))))]" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "data": { + "text/html": [ + "
_NDArray_1 = NDArray.var("X")\n",
+       "assume_dtype(_NDArray_1, DType.float64)\n",
+       "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n",
+       "assume_isfinite(_NDArray_1)\n",
+       "_NDArray_2 = NDArray.var("y")\n",
+       "assume_dtype(_NDArray_2, DType.int64)\n",
+       "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n",
+       "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n",
+       "_NDArray_3 = astype(unique_counts(_NDArray_2)[Int(1)], DType.float64) / NDArray.scalar(Value.float(Float(1000000.0)))\n",
+       "_NDArray_4 = zeros(TupleInt(Int(2)) + TupleInt(Int(20)), OptionalDType.some(DType.float64), OptionalDevice.some(_NDArray_1.device))\n",
+       "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n",
+       "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n",
+       "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n",
+       "_NDArray_4[_IndexKey_1] = mean(_NDArray_1[ndarray_index(unique_inverse(_NDArray_2)[Int(1)] == NDArray.scalar(Value.int(Int(0))))], _OptionalIntOrTuple_1)\n",
+       "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n",
+       "_NDArray_4[_IndexKey_2] = mean(_NDArray_1[ndarray_index(unique_inverse(_NDArray_2)[Int(1)] == NDArray.scalar(Value.int(Int(1))))], _OptionalIntOrTuple_1)\n",
+       "_NDArray_5 = concat(\n",
+       "    TupleNDArray(_NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(0))))] - _NDArray_4[_IndexKey_1])\n",
+       "    + TupleNDArray(_NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(1))))] - _NDArray_4[_IndexKey_2]),\n",
+       "    OptionalInt.some(Int(0)),\n",
+       ")\n",
+       "_NDArray_6 = std(_NDArray_5, _OptionalIntOrTuple_1)\n",
+       "_NDArray_6[ndarray_index(std(_NDArray_5, _OptionalIntOrTuple_1) == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n",
+       "_TupleNDArray_1 = svd(sqrt(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(Int(999998))))) * (_NDArray_5 / _NDArray_6), FALSE)\n",
+       "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n",
+       "_NDArray_7 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_6).T / _TupleNDArray_1[\n",
+       "    Int(1)\n",
+       "][IndexKey.slice(_Slice_1)]\n",
+       "_TupleNDArray_2 = svd(\n",
+       "    (sqrt((NDArray.scalar(Value.int(Int(1000000))) * _NDArray_3) * NDArray.scalar(Value.float(Float(1.0)))) * (_NDArray_4 - (_NDArray_3 @ _NDArray_4)).T).T @ _NDArray_7, FALSE\n",
+       ")\n",
+       "(\n",
+       "    (_NDArray_1 - (_NDArray_3 @ _NDArray_4))\n",
+       "    @ (\n",
+       "        _NDArray_7\n",
+       "        @ _TupleNDArray_2[Int(2)].T[\n",
+       "            IndexKey.multi_axis(\n",
+       "                _MultiAxisIndexKey_1\n",
+       "                + MultiAxisIndexKey(\n",
+       "                    MultiAxisIndexKeyItem.slice(\n",
+       "                        Slice(\n",
+       "                            OptionalInt.none,\n",
+       "                            OptionalInt.some(\n",
+       "                                sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n",
+       "                                .to_value()\n",
+       "                                .to_int\n",
+       "                            ),\n",
+       "                        )\n",
+       "                    )\n",
+       "                )\n",
+       "            )\n",
+       "        ]\n",
+       "    )\n",
+       ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(Int(1))))))]\n",
+       "
\n" ], - "source": [ - "from egglog.exp.array_api_numba import array_api_numba_module\n", - "\n", - "egraph = EGraph([array_api_numba_module])\n", - "egraph.register(X_r2_optimized)\n", - "egraph.run(10000)\n", - "X_r2_numba = egraph.extract(X_r2_optimized)\n", - "X_r2_numba" - ] - }, - { - "cell_type": "markdown", - "id": "969490bb", - "metadata": {}, - "source": [ - "## Compiling back to Python source\n", - "\n", - "Now we finally have a version that we could run with Numba! However, this isn't in NumPy code. What Numba needs\n", - "is a function that uses `numpy`, not our typed dialect.\n", - "\n", - "So we use another module that provides a translation of all our methods into Python strings. The rules in it look like this:\n", - "\n", - "```python\n", - "# the sqrt of an array should use the `np.sqrt` function and be assigned to its own variable, so it can be reused\n", - "rewrite(ndarray_program(sqrt(x))).to((Program(\"np.sqrt(\") + ndarray_program(x) + \")\").assign())\n", - "\n", - "# To compile a setitem call, we first compile the source, assign it to a variable, then add an assignment statement\n", - "mod_x = copy(x)\n", - "mod_x[idx] = y\n", - "assigned_x = ndarray_program(x).assign()\n", - "yield rewrite(ndarray_program(mod_x)).to(\n", - " assigned_x.statement(assigned_x + \"[\" + index_key_program(idx) + \"] = \" + ndarray_program(y))\n", - ")\n", - "```\n", - "\n", - "We pull in all those rewrite rules from the [`egglog.exp.array_api_program_gen` module](https://github.com/egraphs-good/egglog-python/blob/main/python/egglog/exp/array_api_program_gen.py).\n", - "They depend on another module, [`egglog.exp.program_gen` module](https://github.com/egraphs-good/egglog-python/blob/main/python/egglog/exp/program_gen.py), which provides generic translations\n", - "from expressions and statements into strings.\n", - "\n", - "We can run these rules to get out a Python function object:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "3aeae673", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "def __fn(X, y):\n", - " assert X.dtype == np.dtype(np.float64)\n", - " assert X.shape == (1000000, 20,)\n", - " assert np.all(np.isfinite(X))\n", - " assert y.dtype == np.dtype(np.int64)\n", - " assert y.shape == (1000000,)\n", - " assert set(np.unique(y)) == set((0, 1,))\n", - " _0 = y == np.array(0)\n", - " _1 = np.sum(_0)\n", - " _2 = y == np.array(1)\n", - " _3 = np.sum(_2)\n", - " _4 = np.array((_1, _3,)).astype(np.dtype(np.float64))\n", - " _5 = _4 / np.array(1000000.0)\n", - " _6 = np.zeros((2, 20,), dtype=np.dtype(np.float64))\n", - " _7 = np.sum(X[_0], axis=0)\n", - " _8 = _7 / np.array(X[_0].shape[0])\n", - " _6[0, :] = _8\n", - " _9 = np.sum(X[_2], axis=0)\n", - " _10 = _9 / np.array(X[_2].shape[0])\n", - " _6[1, :] = _10\n", - " _11 = _5 @ _6\n", - " _12 = X - _11\n", - " _13 = np.sqrt(np.array((1.0 / 999998)))\n", - " _14 = X[_0] - _6[0, :]\n", - " _15 = X[_2] - _6[1, :]\n", - " _16 = np.concatenate((_14, _15,), axis=0)\n", - " _17 = np.sum(_16, axis=0)\n", - " _18 = _17 / np.array(_16.shape[0])\n", - " _19 = np.expand_dims(_18, 0)\n", - " _20 = _16 - _19\n", - " _21 = np.square(_20)\n", - " _22 = np.sum(_21, axis=0)\n", - " _23 = _22 / np.array(_21.shape[0])\n", - " _24 = np.sqrt(_23)\n", - " _25 = _24 == np.array(0)\n", - " _24[_25] = np.array(1.0)\n", - " _26 = _16 / _24\n", - " _27 = _13 * _26\n", - " _28 = np.linalg.svd(_27, full_matrices=False)\n", - " _29 = _28[1] > np.array(0.0001)\n", - " _30 = _29.astype(np.dtype(np.int32))\n", - " _31 = np.sum(_30)\n", - " _32 = _28[2][:_31, :] / _24\n", - " _33 = _32.T / _28[1][:_31]\n", - " _34 = np.array(1000000) * _5\n", - " _35 = _34 * np.array(1.0)\n", - " _36 = np.sqrt(_35)\n", - " _37 = _6 - _11\n", - " _38 = _36 * _37.T\n", - " _39 = _38.T @ _33\n", - " _40 = np.linalg.svd(_39, full_matrices=False)\n", - " _41 = np.array(0.0001) * _40[1][0]\n", - " _42 = _40[1] > _41\n", - " _43 = _42.astype(np.dtype(np.int32))\n", - " _44 = np.sum(_43)\n", - " _45 = _33 @ _40[2].T[:, :_44]\n", - " _46 = _12 @ _45\n", - " return _46[:, :1]\n", - "\n" - ] - } + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{X}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}isfinite}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{y}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int64}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}value\\PYZus{}one\\PYZus{}of}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{=} \\PY{n}{astype}\\PY{p}{(}\\PY{n}{unique\\PYZus{}counts}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1000000.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{=} \\PY{n}{zeros}\\PY{p}{(}\\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalDType}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalDevice}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{o}{.}\\PY{n}{device}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1} \\PY{o}{=} \\PY{n}{OptionalIntOrTuple}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{IntOrTuple}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]} \\PY{o}{=} \\PY{n}{mean}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]} \\PY{o}{=} \\PY{n}{mean}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{unique\\PYZus{}inverse}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{)}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{=} \\PY{n}{concat}\\PY{p}{(}\n", + " \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]}\\PY{p}{)}\n", + " \\PY{o}{+} \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,}\n", + " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,}\n", + "\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}6} \\PY{o}{=} \\PY{n}{std}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{std}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\\PY{n}{sqrt}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)} \\PY{o}{/} \\PY{n}{Float}\\PY{o}{.}\\PY{n}{from\\PYZus{}int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{999998}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{)}\\PY{p}{,} \\PY{n}{FALSE}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}Slice\\PYZus{}1} \\PY{o}{=} \\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}int}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{=} \\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{/} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\n", + " \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\n", + "\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{]}\n", + "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\n", + " \\PY{p}{(}\\PY{n}{sqrt}\\PY{p}{(}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)} \\PY{o}{*} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{p}{,} \\PY{n}{FALSE}\n", + "\\PY{p}{)}\n", + "\\PY{p}{(}\n", + " \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\\PY{p}{)}\n", + " \\PY{o}{@} \\PY{p}{(}\n", + " \\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\n", + " \\PY{o}{@} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{o}{.}\\PY{n}{T}\\PY{p}{[}\n", + " \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\n", + " \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\n", + " \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\n", + " \\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\n", + " \\PY{n}{Slice}\\PY{p}{(}\n", + " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,}\n", + " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\n", + " \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\n", + " \\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\n", + " \\PY{o}{.}\\PY{n}{to\\PYZus{}int}\n", + " \\PY{p}{)}\\PY{p}{,}\n", + " \\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{p}{]}\n", + " \\PY{p}{)}\n", + "\\PY{p}{)}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", + "\\end{Verbatim}\n" ], - "source": [ - "from egglog.exp.array_api_program_gen import (\n", - " ndarray_function_two,\n", - " array_api_module_string,\n", - ")\n", - "\n", - "egraph = EGraph([array_api_module_string])\n", - "fn_program = ndarray_function_two(X_r2_numba, X_orig, y_orig)\n", - "egraph.register(fn_program)\n", - "egraph.run(10000)\n", - "fn = egraph.load_object(egraph.extract(fn_program.py_object))\n", - "import inspect\n", - "\n", - "print(inspect.getsource(fn))" - ] - }, - { - "cell_type": "markdown", - "id": "6e0405c8", - "metadata": {}, - "source": [ - "We can verify that the function gives the same result:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "a807d66c", - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "assert np.allclose(run_lda(X_np, y_np), fn(X_np, y_np))" - ] - }, - { - "cell_type": "markdown", - "id": "b2a3f1ed", - "metadata": {}, - "source": [ - "Although it isn't the prettiest, we can see that it has only emitted each expression once, for common subexpression\n", - "elimination, and preserves the \"imperative\" aspects of setitem.\n", - "\n", - "## Compiling to Numba\n", - "\n", - "Now we finally have a function we can run with numba:\n" + "text/plain": [ + "_NDArray_1 = NDArray.var(\"X\")\n", + "assume_dtype(_NDArray_1, DType.float64)\n", + "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n", + "assume_isfinite(_NDArray_1)\n", + "_NDArray_2 = NDArray.var(\"y\")\n", + "assume_dtype(_NDArray_2, DType.int64)\n", + "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n", + "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n", + "_NDArray_3 = astype(unique_counts(_NDArray_2)[Int(1)], DType.float64) / NDArray.scalar(Value.float(Float(1000000.0)))\n", + "_NDArray_4 = zeros(TupleInt(Int(2)) + TupleInt(Int(20)), OptionalDType.some(DType.float64), OptionalDevice.some(_NDArray_1.device))\n", + "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n", + "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n", + "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n", + "_NDArray_4[_IndexKey_1] = mean(_NDArray_1[ndarray_index(unique_inverse(_NDArray_2)[Int(1)] == NDArray.scalar(Value.int(Int(0))))], _OptionalIntOrTuple_1)\n", + "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n", + "_NDArray_4[_IndexKey_2] = mean(_NDArray_1[ndarray_index(unique_inverse(_NDArray_2)[Int(1)] == NDArray.scalar(Value.int(Int(1))))], _OptionalIntOrTuple_1)\n", + "_NDArray_5 = concat(\n", + " TupleNDArray(_NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(0))))] - _NDArray_4[_IndexKey_1])\n", + " + TupleNDArray(_NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(1))))] - _NDArray_4[_IndexKey_2]),\n", + " OptionalInt.some(Int(0)),\n", + ")\n", + "_NDArray_6 = std(_NDArray_5, _OptionalIntOrTuple_1)\n", + "_NDArray_6[ndarray_index(std(_NDArray_5, _OptionalIntOrTuple_1) == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n", + "_TupleNDArray_1 = svd(sqrt(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(Int(999998))))) * (_NDArray_5 / _NDArray_6), FALSE)\n", + "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n", + "_NDArray_7 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_6).T / _TupleNDArray_1[\n", + " Int(1)\n", + "][IndexKey.slice(_Slice_1)]\n", + "_TupleNDArray_2 = svd(\n", + " (sqrt((NDArray.scalar(Value.int(Int(1000000))) * _NDArray_3) * NDArray.scalar(Value.float(Float(1.0)))) * (_NDArray_4 - (_NDArray_3 @ _NDArray_4)).T).T @ _NDArray_7, FALSE\n", + ")\n", + "(\n", + " (_NDArray_1 - (_NDArray_3 @ _NDArray_4))\n", + " @ (\n", + " _NDArray_7\n", + " @ _TupleNDArray_2[Int(2)].T[\n", + " IndexKey.multi_axis(\n", + " _MultiAxisIndexKey_1\n", + " + MultiAxisIndexKey(\n", + " MultiAxisIndexKeyItem.slice(\n", + " Slice(\n", + " OptionalInt.none,\n", + " OptionalInt.some(\n", + " sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n", + " .to_value()\n", + " .to_int\n", + " ),\n", + " )\n", + " )\n", + " )\n", + " )\n", + " ]\n", + " )\n", + ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(Int(1))))))]" ] - }, + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "egraph = EGraph([array_api_module])\n", + "egraph.register(X_r2)\n", + "egraph.run(10000)\n", + "X_r2_optimized = egraph.extract(X_r2)\n", + "X_r2_optimized" + ] + }, + { + "cell_type": "markdown", + "id": "30ea4ea4", + "metadata": {}, + "source": [ + "We see that for example expressions that referenced the shape of our input arrays have been resolved to their\n", + "values.\n", + "\n", + "We can also take a look at the e-graph itself, even though it's quite large, where we can see that equivalent\n", + "expressions show up in the same group, or \"e-class\":\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "6417b9e5", + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 9, - "id": "39a69f23", - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/var/folders/xn/05ktz3056kqd9n8frgd6236h0000gn/T/egglog-9e61d62c-d17d-495b-b8db-f1eb3b38dcbb.py:56: NumbaPerformanceWarning: '@' is faster on contiguous arrays, called on (Array(float64, 2, 'C', False, aligned=True), Array(float64, 2, 'A', False, aligned=True))\n", - " _45 = _33 @ _40[2].T[:, :_44]\n" - ] - } + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "\n", + "outer_cluster_32\n", + "\n", + "\n", + "cluster_32\n", + "\n", + "\n", + "\n", + "outer_cluster_48\n", + "\n", + "\n", + "cluster_48\n", + "\n", + "\n", + "\n", + "outer_cluster_92\n", + "\n", + "\n", + "cluster_92\n", + "\n", + "\n", + "\n", + "outer_cluster_155\n", + "\n", + "\n", + "cluster_155\n", + "\n", + "\n", + "\n", + "outer_cluster_34\n", + "\n", + "\n", + "cluster_34\n", + "\n", + "\n", + "\n", + "outer_cluster_91\n", + "\n", + "\n", + "cluster_91\n", + "\n", + "\n", + "\n", + "outer_cluster_72\n", + "\n", + "\n", + "cluster_72\n", + "\n", + "\n", + "\n", + "outer_cluster_190\n", + "\n", + "\n", + "cluster_190\n", + "\n", + "\n", + "\n", + "outer_cluster_147\n", + "\n", + "\n", + "cluster_147\n", + "\n", + "\n", + "\n", + "outer_cluster_58\n", + "\n", + "\n", + "cluster_58\n", + "\n", + "\n", + "\n", + "outer_cluster_62\n", + "\n", + "\n", + "cluster_62\n", + "\n", + "\n", + "\n", + "outer_cluster_143\n", + "\n", + "\n", + "cluster_143\n", + "\n", + "\n", + "\n", + "outer_cluster_75\n", + "\n", + "\n", + "cluster_75\n", + "\n", + "\n", + "\n", + "outer_cluster_118\n", + "\n", + "\n", + "cluster_118\n", + "\n", + "\n", + "\n", + "outer_cluster_105\n", + "\n", + "\n", + "cluster_105\n", + "\n", + "\n", + "\n", + "outer_cluster_71\n", + "\n", + "\n", + "cluster_71\n", + "\n", + "\n", + "\n", + "outer_cluster_141\n", + "\n", + "\n", + "cluster_141\n", + "\n", + "\n", + "\n", + "outer_cluster_142\n", + "\n", + "\n", + "cluster_142\n", + "\n", + "\n", + "\n", + "outer_cluster_52\n", + "\n", + "\n", + "cluster_52\n", + "\n", + "\n", + "\n", + "outer_cluster_56\n", + "\n", + "\n", + "cluster_56\n", + "\n", + "\n", + "\n", + "outer_cluster_188\n", + "\n", + "\n", + "cluster_188\n", + "\n", + "\n", + "\n", + "outer_cluster_69\n", + "\n", + "\n", + "cluster_69\n", + "\n", + "\n", + "\n", + "outer_cluster_178\n", + "\n", + "\n", + "cluster_178\n", + "\n", + "\n", + "\n", + "outer_cluster_140\n", + "\n", + "\n", + "cluster_140\n", + "\n", + "\n", + "\n", + "outer_cluster_187\n", + "\n", + "\n", + "cluster_187\n", + "\n", + "\n", + "\n", + "outer_cluster_95\n", + "\n", + "\n", + "cluster_95\n", + "\n", + "\n", + "\n", + "outer_cluster_12\n", + "\n", + "\n", + "cluster_12\n", + "\n", + "\n", + "\n", + "outer_cluster_102\n", + "\n", + "\n", + "cluster_102\n", + "\n", + "\n", + "\n", + "outer_cluster_67\n", + "\n", + "\n", + "cluster_67\n", + "\n", + "\n", + "\n", + "outer_cluster_115\n", + "\n", + "\n", + "cluster_115\n", + "\n", + "\n", + "\n", + "outer_cluster_63\n", + "\n", + "\n", + "cluster_63\n", + "\n", + "\n", + "\n", + "outer_cluster_127\n", + "\n", + "\n", + "cluster_127\n", + "\n", + "\n", + "\n", + "outer_cluster_146\n", + "\n", + "\n", + "cluster_146\n", + "\n", + "\n", + "\n", + "outer_cluster_109\n", + "\n", + "\n", + "cluster_109\n", + "\n", + "\n", + "\n", + "outer_cluster_191\n", + "\n", + "\n", + "cluster_191\n", + "\n", + "\n", + "\n", + "outer_cluster_37\n", + "\n", + "\n", + "cluster_37\n", + "\n", + "\n", + "\n", + "outer_cluster_79\n", + "\n", + "\n", + "cluster_79\n", + "\n", + "\n", + "\n", + "outer_cluster_122\n", + "\n", + "\n", + "cluster_122\n", + "\n", + "\n", + "\n", + "outer_cluster_163\n", + "\n", + "\n", + "cluster_163\n", + "\n", + "\n", + "\n", + "outer_cluster_145\n", + "\n", + "\n", + "cluster_145\n", + "\n", + "\n", + "\n", + "outer_cluster_106\n", + "\n", + "\n", + "cluster_106\n", + "\n", + "\n", + "\n", + "outer_cluster_2\n", + "\n", + "\n", + "cluster_2\n", + "\n", + "\n", + "\n", + "outer_cluster_149\n", + "\n", + "\n", + "cluster_149\n", + "\n", + "\n", + "\n", + "outer_cluster_126\n", + "\n", + "\n", + "cluster_126\n", + "\n", + "\n", + "\n", + "outer_cluster_110\n", + "\n", + "\n", + "cluster_110\n", + "\n", + "\n", + "\n", + "outer_cluster_131\n", + "\n", + "\n", + "cluster_131\n", + "\n", + "\n", + "\n", + "outer_cluster_171\n", + "\n", + "\n", + "cluster_171\n", + "\n", + "\n", + "\n", + "outer_cluster_99\n", + "\n", + "\n", + "cluster_99\n", + "\n", + "\n", + "\n", + "outer_cluster_135\n", + "\n", + "\n", + "cluster_135\n", + "\n", + "\n", + "\n", + "outer_cluster_182\n", + "\n", + "\n", + "cluster_182\n", + "\n", + "\n", + "\n", + "outer_cluster_8\n", + "\n", + "\n", + "cluster_8\n", + "\n", + "\n", + "\n", + "outer_cluster_78\n", + "\n", + "\n", + "cluster_78\n", + "\n", + "\n", + "\n", + "outer_cluster_167\n", + "\n", + "\n", + "cluster_167\n", + "\n", + "\n", + "\n", + "outer_cluster_172\n", + "\n", + "\n", + "cluster_172\n", + "\n", + "\n", + "\n", + "outer_cluster_169\n", + "\n", + "\n", + "cluster_169\n", + "\n", + "\n", + "\n", + "outer_cluster_36\n", + "\n", + "\n", + "cluster_36\n", + "\n", + "\n", + "\n", + "outer_cluster_76\n", + "\n", + "\n", + "cluster_76\n", + "\n", + "\n", + "\n", + "outer_cluster_61\n", + "\n", + "\n", + "cluster_61\n", + "\n", + "\n", + "\n", + "outer_cluster_157\n", + "\n", + "\n", + "cluster_157\n", + "\n", + "\n", + "\n", + "outer_cluster_173\n", + "\n", + "\n", + "cluster_173\n", + "\n", + "\n", + "\n", + "outer_cluster_164\n", + "\n", + "\n", + "cluster_164\n", + "\n", + "\n", + "\n", + "outer_cluster_33\n", + "\n", + "\n", + "cluster_33\n", + "\n", + "\n", + "\n", + "outer_cluster_83\n", + "\n", + "\n", + "cluster_83\n", + "\n", + "\n", + "\n", + "outer_cluster_116\n", + "\n", + "\n", + "cluster_116\n", + "\n", + "\n", + "\n", + "outer_cluster_168\n", + "\n", + "\n", + "cluster_168\n", + "\n", + "\n", + "\n", + "outer_cluster_100\n", + "\n", + "\n", + "cluster_100\n", + "\n", + "\n", + "\n", + "outer_cluster_108\n", + "\n", + "\n", + "cluster_108\n", + "\n", + "\n", + "\n", + "outer_cluster_181\n", + "\n", + "\n", + "cluster_181\n", + "\n", + "\n", + "\n", + "outer_cluster_90\n", + "\n", + "\n", + "cluster_90\n", + "\n", + "\n", + "\n", + "outer_cluster_153\n", + "\n", + "\n", + "cluster_153\n", + "\n", + "\n", + "\n", + "outer_cluster_175\n", + "\n", + "\n", + "cluster_175\n", + "\n", + "\n", + "\n", + "outer_cluster_137\n", + "\n", + "\n", + "cluster_137\n", + "\n", + "\n", + "\n", + "outer_cluster_89\n", + "\n", + "\n", + "cluster_89\n", + "\n", + "\n", + "\n", + "outer_cluster_82\n", + "\n", + "\n", + "cluster_82\n", + "\n", + "\n", + "\n", + "outer_cluster_44\n", + "\n", + "\n", + "cluster_44\n", + "\n", + "\n", + "\n", + "outer_cluster_180\n", + "\n", + "\n", + "cluster_180\n", + "\n", + "\n", + "\n", + "outer_cluster_189\n", + "\n", + "\n", + "cluster_189\n", + "\n", + "\n", + "\n", + "outer_cluster_179\n", + "\n", + "\n", + "cluster_179\n", + "\n", + "\n", + "\n", + "outer_cluster_70\n", + "\n", + "\n", + "cluster_70\n", + "\n", + "\n", + "\n", + "outer_cluster_57\n", + "\n", + "\n", + "cluster_57\n", + "\n", + "\n", + "\n", + "outer_cluster_121\n", + "\n", + "\n", + "cluster_121\n", + "\n", + "\n", + "\n", + "outer_cluster_31\n", + "\n", + "\n", + "cluster_31\n", + "\n", + "\n", + "\n", + "outer_cluster_123\n", + "\n", + "\n", + "cluster_123\n", + "\n", + "\n", + "\n", + "outer_cluster_68\n", + "\n", + "\n", + "cluster_68\n", + "\n", + "\n", + "\n", + "outer_cluster_50\n", + "\n", + "\n", + "cluster_50\n", + "\n", + "\n", + "\n", + "outer_cluster_151\n", + "\n", + "\n", + "cluster_151\n", + "\n", + "\n", + "\n", + "outer_cluster_77\n", + "\n", + "\n", + "cluster_77\n", + "\n", + "\n", + "\n", + "outer_cluster_74\n", + "\n", + "\n", + "cluster_74\n", + "\n", + "\n", + "\n", + "outer_cluster_101\n", + "\n", + "\n", + "cluster_101\n", + "\n", + "\n", + "\n", + "outer_cluster_152\n", + "\n", + "\n", + "cluster_152\n", + "\n", + "\n", + "\n", + "outer_cluster_130\n", + "\n", + "\n", + "cluster_130\n", + "\n", + "\n", + "\n", + "outer_cluster_161\n", + "\n", + "\n", + "cluster_161\n", + "\n", + "\n", + "\n", + "outer_cluster_148\n", + "\n", + "\n", + "cluster_148\n", + "\n", + "\n", + "\n", + "outer_cluster_80\n", + "\n", + "\n", + "cluster_80\n", + "\n", + "\n", + "\n", + "outer_cluster_111\n", + "\n", + "\n", + "cluster_111\n", + "\n", + "\n", + "\n", + "outer_cluster_183\n", + "\n", + "\n", + "cluster_183\n", + "\n", + "\n", + "\n", + "outer_cluster_59\n", + "\n", + "\n", + "cluster_59\n", + "\n", + "\n", + "\n", + "outer_cluster_159\n", + "\n", + "\n", + "cluster_159\n", + "\n", + "\n", + "\n", + "outer_cluster_103\n", + "\n", + "\n", + "cluster_103\n", + "\n", + "\n", + "\n", + "outer_cluster_117\n", + "\n", + "\n", + "cluster_117\n", + "\n", + "\n", + "\n", + "outer_cluster_158\n", + "\n", + "\n", + "cluster_158\n", + "\n", + "\n", + "\n", + "outer_cluster_87\n", + "\n", + "\n", + "cluster_87\n", + "\n", + "\n", + "\n", + "outer_cluster_96\n", + "\n", + "\n", + "cluster_96\n", + "\n", + "\n", + "\n", + "outer_cluster_98\n", + "\n", + "\n", + "cluster_98\n", + "\n", + "\n", + "\n", + "outer_cluster_166\n", + "\n", + "\n", + "cluster_166\n", + "\n", + "\n", + "\n", + "outer_cluster_133\n", + "\n", + "\n", + "cluster_133\n", + "\n", + "\n", + "\n", + "outer_cluster_184\n", + "\n", + "\n", + "cluster_184\n", + "\n", + "\n", + "\n", + "outer_cluster_107\n", + "\n", + "\n", + "cluster_107\n", + "\n", + "\n", + "\n", + "outer_cluster_162\n", + "\n", + "\n", + "cluster_162\n", + "\n", + "\n", + "\n", + "outer_cluster_144\n", + "\n", + "\n", + "cluster_144\n", + "\n", + "\n", + "\n", + "outer_cluster_170\n", + "\n", + "\n", + "cluster_170\n", + "\n", + "\n", + "\n", + "outer_cluster_160\n", + "\n", + "\n", + "cluster_160\n", + "\n", + "\n", + "\n", + "outer_cluster_16\n", + "\n", + "\n", + "cluster_16\n", + "\n", + "\n", + "\n", + "outer_cluster_47\n", + "\n", + "\n", + "cluster_47\n", + "\n", + "\n", + "\n", + "outer_cluster_49\n", + "\n", + "\n", + "cluster_49\n", + "\n", + "\n", + "\n", + "outer_cluster_138\n", + "\n", + "\n", + "cluster_138\n", + "\n", + "\n", + "\n", + "outer_cluster_185\n", + "\n", + "\n", + "cluster_185\n", + "\n", + "\n", + "\n", + "outer_cluster_176\n", + "\n", + "\n", + "cluster_176\n", + "\n", + "\n", + "\n", + "outer_cluster_65\n", + "\n", + "\n", + "cluster_65\n", + "\n", + "\n", + "\n", + "outer_cluster_Int_to_py-7586556743040283621-value\n", + "\n", + "\n", + "cluster_Int_to_py-7586556743040283621-value\n", + "\n", + "\n", + "\n", + "outer_cluster_Int_to_py-11951456526892775522-value\n", + "\n", + "\n", + "cluster_Int_to_py-11951456526892775522-value\n", + "\n", + "\n", + "\n", + "outer_cluster_Int_to_py-6079675520328773069-value\n", + "\n", + "\n", + "cluster_Int_to_py-6079675520328773069-value\n", + "\n", + "\n", + "\n", + "outer_cluster_Int_to_py-103947256882385308-value\n", + "\n", + "\n", + "cluster_Int_to_py-103947256882385308-value\n", + "\n", + "\n", + "\n", + "outer_cluster_Int_to_py-5092353580987650850-value\n", + "\n", + "\n", + "cluster_Int_to_py-5092353580987650850-value\n", + "\n", + "\n", + "\n", + "outer_cluster_Int_to_py-1870696621799859130-value\n", + "\n", + "\n", + "cluster_Int_to_py-1870696621799859130-value\n", + "\n", + "\n", + "\n", + "outer_cluster_Boolean_to_py-155920885323577962-value\n", + "\n", + "\n", + "cluster_Boolean_to_py-155920885323577962-value\n", + "\n", + "\n", + "\n", + "outer_cluster_Int_to_py-12938778466233897741-value\n", + "\n", + "\n", + "cluster_Int_to_py-12938778466233897741-value\n", + "\n", + "\n", + "\n", + "outer_cluster_139\n", + "\n", + "\n", + "cluster_139\n", + "\n", + "\n", + "\n", + "outer_cluster_177\n", + "\n", + "\n", + "cluster_177\n", + "\n", + "\n", + "\n", + "outer_cluster_186\n", + "\n", + "\n", + "cluster_186\n", + "\n", + "\n", + "\n", + "outer_cluster_43\n", + "\n", + "\n", + "cluster_43\n", + "\n", + "\n", + "\n", + "outer_cluster_203\n", + "\n", + "\n", + "cluster_203\n", + "\n", + "\n", + "\n", + "outer_cluster_46\n", + "\n", + "\n", + "cluster_46\n", + "\n", + "\n", + "\n", + "outer_cluster_212\n", + "\n", + "\n", + "cluster_212\n", + "\n", + "\n", + "\n", + "outer_cluster_42\n", + "\n", + "\n", + "cluster_42\n", + "\n", + "\n", + "\n", + "outer_cluster_45\n", + "\n", + "\n", + "cluster_45\n", + "\n", + "\n", + "\n", + "outer_cluster_38\n", + "\n", + "\n", + "cluster_38\n", + "\n", + "\n", + "\n", + "outer_cluster_104\n", + "\n", + "\n", + "cluster_104\n", + "\n", + "\n", + "\n", + "outer_cluster_112\n", + "\n", + "\n", + "cluster_112\n", + "\n", + "\n", + "\n", + "outer_cluster_113\n", + "\n", + "\n", + "cluster_113\n", + "\n", + "\n", + "\n", + "outer_cluster_165\n", + "\n", + "\n", + "cluster_165\n", + "\n", + "\n", + "\n", + "outer_cluster_85\n", + "\n", + "\n", + "cluster_85\n", + "\n", + "\n", + "\n", + "outer_cluster_124\n", + "\n", + "\n", + "cluster_124\n", + "\n", + "\n", + "\n", + "outer_cluster_30\n", + "\n", + "\n", + "cluster_30\n", + "\n", + "\n", + "\n", + "outer_cluster_19\n", + "\n", + "\n", + "cluster_19\n", + "\n", + "\n", + "\n", + "outer_cluster_201\n", + "\n", + "\n", + "cluster_201\n", + "\n", + "\n", + "\n", + "outer_cluster_198\n", + "\n", + "\n", + "cluster_198\n", + "\n", + "\n", + "\n", + "outer_cluster_22\n", + "\n", + "\n", + "cluster_22\n", + "\n", + "\n", + "\n", + "outer_cluster_greater_zero-1143242824664700181-value\n", + "\n", + "\n", + "cluster_greater_zero-1143242824664700181-value\n", + "\n", + "\n", + "\n", + "outer_cluster_greater_zero-13770179520251441998-value\n", + "\n", + "\n", + "cluster_greater_zero-13770179520251441998-value\n", + "\n", + "\n", + "\n", + "outer_cluster_greater_zero-14757501459592564217-value\n", + "\n", + "\n", + "cluster_greater_zero-14757501459592564217-value\n", + "\n", + "\n", + "\n", + "outer_cluster_greater_zero-2598150418935018079-value\n", + "\n", + "\n", + "cluster_greater_zero-2598150418935018079-value\n", + "\n", + "\n", + "\n", + "outer_cluster_greater_zero-12107377412216353484-value\n", + "\n", + "\n", + "cluster_greater_zero-12107377412216353484-value\n", + "\n", + "\n", + "\n", + "outer_cluster_93\n", + "\n", + "\n", + "cluster_93\n", + "\n", + "\n", + "\n", + "outer_cluster_156\n", + "\n", + "\n", + "cluster_156\n", + "\n", + "\n", + "\n", + "outer_cluster_150\n", + "\n", + "\n", + "cluster_150\n", + "\n", + "\n", + "\n", + "outer_cluster_200\n", + "\n", + "\n", + "cluster_200\n", + "\n", + "\n", + "\n", + "outer_cluster_136\n", + "\n", + "\n", + "cluster_136\n", + "\n", + "\n", + "\n", + "outer_cluster_210\n", + "\n", + "\n", + "cluster_210\n", + "\n", + "\n", + "\n", + "outer_cluster_213\n", + "\n", + "\n", + "cluster_213\n", + "\n", + "\n", + "\n", + "outer_cluster_35\n", + "\n", + "\n", + "cluster_35\n", + "\n", + "\n", + "\n", + "outer_cluster_197\n", + "\n", + "\n", + "cluster_197\n", + "\n", + "\n", + "\n", + "outer_cluster_174\n", + "\n", + "\n", + "cluster_174\n", + "\n", + "\n", + "\n", + "outer_cluster_208\n", + "\n", + "\n", + "cluster_208\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_dtype-15121139857639374588:s->assume_isfinite-10080759905092916392\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_isfinite-10080759905092916392:s->assume_shape-14591484260056516843\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_dtype-10080759905092916392:s->assume_shape-14591484260056516843\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_shape-14591484260056516843:s->assume_dtype-3429551472952562336\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_shape-14591484260056516843:s->NDArray_shape-15121139857639374588\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_dtype-11743562013128004906:s->assume_dtype-3429551472952562336\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_dtype-3429551472952562336:s->NDArray_dtype-10080759905092916392\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_device-15121139857639374588:s->asarray-9510298863856844727\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "asarray-9510298863856844727:s->assume_isfinite-10080759905092916392\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float___truediv__-12808993487988576005:s->Float_rational-0\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float___truediv__-12808993487988576005:s->Float_from_int-11951456526892775522\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float_from_int-11951456526892775522:s->Int___sub__-2601583573127157282\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float_from_int-12938778466233897741:s->TupleInt_length-11379923615081194535\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt_length-11379923615081194535:s->NDArray_shape-7742477628363861583\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float___truediv__-5949890542083451333:s->Float_from_int-12938778466233897741\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float___truediv__-5949890542083451333:s->Float___truediv__-5949890542083451333\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___sub__-2601583573127157282:s->Int___init__-16347205588787662656\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___sub__-2601583573127157282:s->Int___init__-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-11068081844434038611:s->MultiAxisIndexKey___add__-7546443524583315781\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-7546443524583315781:s->MultiAxisIndexKey___init__-9353306107957757443\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-7546443524583315781:s->MultiAxisIndexKey___init__-17771263905015585321\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-2961965818023366657:s->MultiAxisIndexKey___add__-9019874688858188702\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-9019874688858188702:s->MultiAxisIndexKey___init__-9353306107957757443\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-9019874688858188702:s->MultiAxisIndexKey___init__-9665147878604913367\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_slice-4520820669176069863:s->Slice___init__-15501507093852132239\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Slice___init__-15501507093852132239:s->OptionalInt_some-11224002729757616573\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-2650124047376210733:s->MultiAxisIndexKey___add__-4155431249018709085\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-4155431249018709085:s->MultiAxisIndexKey___init__-9353306107957757443\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-4155431249018709085:s->MultiAxisIndexKey___init__-4312926155411299247\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-7690503999922668929:s->NDArray___eq__-17968234112188297122\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-17968234112188297122:s->TupleNDArray___getitem__-10045558824545728354\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-17968234112188297122:s->NDArray___getitem__-6343722845416298339\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-3689419615158525606:s->MultiAxisIndexKey___add__-10696952293987308628\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-10696952293987308628:s->MultiAxisIndexKey___init__-9353306107957757443\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-10696952293987308628:s->MultiAxisIndexKey___init__-10392601675740072316\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-10236680790416494354:s->NDArray___eq__-7887474207095380730\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-7887474207095380730:s->NDArray___getitem__-16424482750509214731\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-7887474207095380730:s->TupleNDArray___getitem__-10045558824545728354\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-4468847040734877209:s->NDArray___eq__-3677844317228415595\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-3677844317228415595:s->NDArray_scalar-3845340500482103568\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-3677844317228415595:s->std-4851945112178408602\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_int-12938778466233897741:s->Int___sub__-11477953740632672431\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___sub__-11477953740632672431:s->TupleValue_length-883374682458736911\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___sub__-11477953740632672431:s->Int___add__-17495654355659155035\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-9457253364840142751:s->NDArray___eq__-5948126446311695931\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-5948126446311695931:s->asarray-17776165865978447989\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-5948126446311695931:s->NDArray_scalar-3845340500482103568\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-1091269196223507527:s->NDArray___eq__-14314110614928331155\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-14314110614928331155:s->NDArray_scalar-14757501459592564217\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-14314110614928331155:s->assume_value_one_of-5323778840018127892\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-5456168980075999428:s->MultiAxisIndexKey___add__-8188473634840644445\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-8188473634840644445:s->MultiAxisIndexKey___init__-9353306107957757443\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-8188473634840644445:s->MultiAxisIndexKey___init__-12159351040657546138\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-7742477628363861583:s->reshape-4112525690760736104\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue_length-51973628441192654:s->TupleValue___init__-14757501459592564217\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___init__-14757501459592564217:s->TupleValue___getitem__-4148863126349750477\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue_length-883374682458736911:s->TupleValue___init__-3845340500482103568\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___init__-3845340500482103568:s->TupleValue___getitem__-7786309113067083429\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___add__-17495654355659155035:s->Int___sub__-11477953740632672431\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___add__-17495654355659155035:s->Int___init__-5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_to_int-7118971088111087942:s->NDArray_to_value-1247190081547085489\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_to_value-1247190081547085489:s->sum-1681433789052220133\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_to_int-5352221723193614120:s->NDArray_to_value-17927184790339163283\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_to_value-17927184790339163283:s->sum-1955564354691009820\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue_length-467762655970733886:s->TupleValue___add__-15259460202689358531\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___add__-15259460202689358531:s->TupleValue___init__-14757501459592564217\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___add__-15259460202689358531:s->TupleValue___init__-3845340500482103568\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue_length-18083105675662741245:s->possible_values-12211324669098738792\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "possible_values-12211324669098738792:s->NDArray_index-12579319251068649370\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___getitem__-14078601210367663714:s->NDArray_shape-12782857580910319779\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-12782857580910319779:s->unique_values-12782857580910319779\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___getitem__-11605336705429392564:s->NDArray_shape-10080759905092916392\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-10080759905092916392:s->assume_shape-14591484260056516843\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___getitem__-12686509587440430679:s->TupleInt___init__-103947256882385308\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___init__-103947256882385308:s->Int___init__-6755155689022739364\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___getitem__-7967890718712059612:s->TupleValue_length-51973628441192654\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___getitem__-7967890718712059612:s->TupleInt___add__-13243224121832505654\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___add__-13243224121832505654:s->TupleInt___init__-103947256882385308\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___add__-13243224121832505654:s->NDArray_shape-1714775736476281168\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-12159351040657546138:s->MultiAxisIndexKeyItem_slice-6287570034093543685\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-9665147878604913367:s->MultiAxisIndexKeyItem_slice-3793366872040910914\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_slice-6287570034093543685:s->Slice___init__-14445438978175812750\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-17771263905015585321:s->MultiAxisIndexKeyItem_int-12938778466233897741\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_int-12938778466233897741:s->TupleValue_length-883374682458736911\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-10392601675740072316:s->MultiAxisIndexKeyItem_slice-4520820669176069863\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_slice-4520820669176069863:s->Slice___init__-15501507093852132239\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_slice-3793366872040910914:s->Slice___init__-1162291712589082458\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Slice___init__-14445438978175812750:s->OptionalInt_some-12990752094675090395\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Slice___init__-1162291712589082458:s->OptionalInt_some-12938778466233897741\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-11120055472875231265:s->Value_float-5248274466311228812\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_float-5248274466311228812:s->Float_rational-17615343019692007359\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "asarray-7902703286805427734:s->asarray-7902703286805427734\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-17483047916985507424:s->IndexKey_multi_axis-2650124047376210733\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-17483047916985507424:s->NDArray___setitem__-18325169333216085054\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-18325169333216085054:s->IndexKey_multi_axis-11068081844434038611\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-18325169333216085054:s->NDArray___setitem__-7453141863274628760\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-18325169333216085054:s->mean-3476503888447580293\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "mean-9206860573968271485:s->NDArray___getitem__-16307929054953181812\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "mean-9206860573968271485:s->OptionalIntOrTuple_some-6859102945905124672\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-16307929054953181812:s->asarray-9510298863856844727\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-16307929054953181812:s->ndarray_index-7690503999922668929\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "concat-9071020324919791953:s->TupleNDArray___add__-17612194977553982959\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___add__-17612194977553982959:s->TupleNDArray___init__-14497633317386600947\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___add__-17612194977553982959:s->TupleNDArray___init__-6131649148769965723\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-18135092377765138894:s->TupleValue_length-51973628441192654\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-18135092377765138894:s->svd-7253966389981509278\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "svd-7253966389981509278:s->NDArray___mul__-8455018010728142919\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_T-2858018561140981349:s->NDArray___truediv__-11279504549742320031\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-11279504549742320031:s->NDArray___setitem__-5767087113385015795\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-11279504549742320031:s->NDArray___getitem__-9914932780259612220\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-18178625676753040942:s->assume_isfinite-10080759905092916392\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-18178625676753040942:s->ndarray_index-1091269196223507527\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-11026489642259430172:s->IndexKey_multi_axis-2961965818023366657\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-11026489642259430172:s->NDArray___matmul__-7132500556515696557\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-7132500556515696557:s->NDArray___sub__-8877293197236476153\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-7132500556515696557:s->NDArray___matmul__-10968585808826125111\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-15656725660214344740:s->astype-6261542238027864055\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-15656725660214344740:s->NDArray_scalar-2598150418935018079\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "astype-6261542238027864055:s->NDArray_dtype-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "astype-6261542238027864055:s->TupleNDArray___getitem__-15957548086918070248\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-2598150418935018079:s->Value_float-15173113486080567242\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-9557034512502171054:s->NDArray___setitem__-18325169333216085054\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-9557034512502171054:s->NDArray___truediv__-15656725660214344740\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-9788377807842481490:s->concat-9071020324919791953\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-9788377807842481490:s->NDArray___setitem__-5767087113385015795\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-5767087113385015795:s->ndarray_index-4468847040734877209\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-5767087113385015795:s->NDArray_scalar-12107377412216353484\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-5767087113385015795:s->std-4851945112178408602\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_T-10444575304181264970:s->NDArray___mul__-7696624279617524538\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-7696624279617524538:s->NDArray_T-17147757364762811680\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-7696624279617524538:s->ndarray-sqrt-5404195351634806774\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-9914932780259612220:s->IndexKey_multi_axis-3689419615158525606\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-9914932780259612220:s->TupleNDArray___getitem__-1818913068061409678\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-14757501459592564217:s->TupleValue___getitem__-9658389681233211557\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-9658389681233211557:s->TupleValue___init__-14757501459592564217\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-16424482750509214731:s->IndexKey_int-12938778466233897741\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-16424482750509214731:s->concat-430064524623572644\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "concat-430064524623572644:s->TupleNDArray___init__-12782857580910319779\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-3215265837560371319:s->NDArray_T-2858018561140981349\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-3215265837560371319:s->NDArray___getitem__-11494903289568215254\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-11494903289568215254:s->IndexKey_slice-4520820669176069863\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-11494903289568215254:s->TupleNDArray___getitem__-18135092377765138894\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-1818913068061409678:s->TupleValue_length-467762655970733886\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-1818913068061409678:s->svd-7253966389981509278\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-2205987174022554874:s->IndexKey_multi_axis-11068081844434038611\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-2205987174022554874:s->NDArray___setitem__-18325169333216085054\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___gt__-15651908559655936539:s->TupleNDArray___getitem__-18135092377765138894\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___gt__-15651908559655936539:s->NDArray_scalar-1143242824664700181\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___gt__-8664676620264668937:s->TupleNDArray___getitem__-17539377729349800285\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___gt__-8664676620264668937:s->NDArray___mul__-8440009558605893705\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-17539377729349800285:s->TupleValue_length-883374682458736911\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-17539377729349800285:s->svd-2189404700831293460\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-8440009558605893705:s->NDArray_scalar-1143242824664700181\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-8440009558605893705:s->NDArray___getitem__-17758114586016463110\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "asarray-17776165865978447989:s->reshape-4112525690760736104\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-3845340500482103568:s->TupleValue___getitem__-1353837537593392198\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "sum-1955564354691009820:s->astype-14592420363448682842\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "astype-14592420363448682842:s->NDArray___gt__-15651908559655936539\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-13476223401931994896:s->IndexKey_multi_axis-5456168980075999428\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-13476223401931994896:s->NDArray_T-15484955256727723166\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_T-15484955256727723166:s->TupleNDArray___getitem__-10680274783444675613\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-15121139857639374588:s->assume_isfinite-10080759905092916392\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-7453141863274628760:s->IndexKey_multi_axis-2650124047376210733\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-7453141863274628760:s->mean-9206860573968271485\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-7453141863274628760:s->zeros-16505489609336576318\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "mean-3476503888447580293:s->OptionalIntOrTuple_some-6859102945905124672\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "mean-3476503888447580293:s->NDArray___getitem__-3836913244690017957\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-10680274783444675613:s->TupleValue_length-18083105675662741245\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-10680274783444675613:s->svd-2189404700831293460\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "astype-12468708834165933853:s->NDArray___gt__-8664676620264668937\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-15588902513610108474:s->NDArray_index-1182067134106770624\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-1182067134106770624:s->TupleNDArray___getitem__-17539377729349800285\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-17758114586016463110:s->TupleNDArray___getitem__-17539377729349800285\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_float-15173113486080567242:s->Float_rational-5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-3836913244690017957:s->assume_isfinite-10080759905092916392\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-3836913244690017957:s->ndarray_index-10236680790416494354\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-10045558824545728354:s->TupleInt_length-11379923615081194535\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-10045558824545728354:s->unique_inverse-7742477628363861583\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-6343722845416298339:s->NDArray_vector-467762655970733886\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-12107377412216353484:s->Value_float-6235596405652351031\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_float-6235596405652351031:s->Float___init__-10858178701590265856\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "sum-1681433789052220133:s->astype-12468708834165933853\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-13392291772433010205:s->NDArray_T-10444575304181264970\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-13392291772433010205:s->NDArray___truediv__-3215265837560371319\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-15957548086918070248:s->Int___sub__-11477953740632672431\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-15957548086918070248:s->unique_counts-7742477628363861583\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "reshape-4112525690760736104:s->reshape-4112525690760736104\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_value_one_of-5323778840018127892:s->TupleValue___add__-15259460202689358531\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_value_one_of-5323778840018127892:s->assume_shape-8316602628326787375\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_shape-8316602628326787375:s->TupleInt___init__-1870696621799859130\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "std-4851945112178408602:s->OptionalIntOrTuple_some-6859102945905124672\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "std-4851945112178408602:s->concat-9071020324919791953\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "svd-2189404700831293460:s->NDArray___matmul__-13392291772433010205\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "unique_counts-7742477628363861583:s->reshape-4112525690760736104\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-8455018010728142919:s->NDArray___truediv__-9788377807842481490\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-8455018010728142919:s->ndarray-sqrt-4416873412293684555\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray-sqrt-4416873412293684555:s->NDArray_scalar-11120055472875231265\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "zeros-16505489609336576318:s->TupleInt___add__-10752996994297486686\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "zeros-16505489609336576318:s->OptionalDType_some-3429551472952562336\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "zeros-16505489609336576318:s->OptionalDevice_some-5144327209428843504\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___add__-10752996994297486686:s->TupleInt___init__-103947256882385308\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___add__-10752996994297486686:s->TupleInt___init__-6079675520328773069\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalDType_some-3429551472952562336:s->NDArray_dtype-11743562013128004906\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalDevice_some-5144327209428843504:s->NDArray_device-15121139857639374588\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-13770179520251441998:s->Value_int-1870696621799859130\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_int-1870696621799859130:s->Int___init__-16347205588787662656\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-9812641508136405718:s->asarray-9510298863856844727\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-9812641508136405718:s->ndarray_index-9457253364840142751\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-4099386548708531027:s->NDArray___truediv__-15656725660214344740\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-4099386548708531027:s->NDArray_scalar-13770179520251441998\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_T-17147757364762811680:s->NDArray___sub__-1374586120005010617\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-1374586120005010617:s->NDArray___setitem__-18325169333216085054\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-1374586120005010617:s->NDArray___matmul__-9557034512502171054\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-8877293197236476153:s->assume_isfinite-10080759905092916392\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-8877293197236476153:s->NDArray___matmul__-9557034512502171054\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-9558798608273926456:s->NDArray___getitem__-18178625676753040942\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-9558798608273926456:s->NDArray___getitem__-2205987174022554874\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-10968585808826125111:s->NDArray___truediv__-3215265837560371319\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-10968585808826125111:s->NDArray___getitem__-13476223401931994896\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "unique_inverse-7742477628363861583:s->assume_value_one_of-5323778840018127892\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray-sqrt-5404195351634806774:s->NDArray___mul__-3756686807776082277\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-3756686807776082277:s->NDArray_scalar-12107377412216353484\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-3756686807776082277:s->NDArray___mul__-4099386548708531027\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-10430407918099810154:s->NDArray___getitem__-17483047916985507424\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-10430407918099810154:s->NDArray___getitem__-9812641508136405718\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___init__-12782857580910319779:s->unique_values-12782857580910319779\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-13683004811263061306:s->unique_inverse-7742477628363861583\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "unique_values-12782857580910319779:s->NDArray_vector-18083105675662741245\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_vector-18083105675662741245:s->possible_values-12211324669098738792\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "unique_values-7742477628363861583:s->asarray-17776165865978447989\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_vector-467762655970733886:s->possible_values-13042725723116283049\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "possible_values-13042725723116283049:s->NDArray_index-17067340853146132798\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-1353837537593392198:s->possible_values-12211324669098738792\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___init__-1870696621799859130:s->TupleInt___getitem__-11605336705429392564\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalInt_some-11224002729757616573:s->Value_to_int-5352221723193614120\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalInt_some-12938778466233897741:s->Int___init__-5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalInt_some-12990752094675090395:s->Value_to_int-7118971088111087942\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-11951456526892775522:s->Int___sub__-2601583573127157282\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-6079675520328773069:s->TupleValue_length-18083105675662741245\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-103947256882385308:s->TupleInt___getitem__-12686509587440430679\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-1870696621799859130:s->TupleInt___getitem__-11605336705429392564\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-12938778466233897741:s->TupleValue_length-883374682458736911\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-1714775736476281168:s->assume_shape-8316602628326787375\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___init__-6079675520328773069:s->TupleValue_length-467762655970733886\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___init__-12938778466233897741:s->TupleInt_length-11379923615081194535\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___init__-14497633317386600947:s->NDArray___sub__-10430407918099810154\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___init__-6131649148769965723:s->NDArray___sub__-9558798608273926456\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-7786309113067083429:s->TupleValue___add__-15259460202689358531\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-12579319251068649370:s->concat-430064524623572644\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-17067340853146132798:s->assume_shape-8316602628326787375\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-4148863126349750477:s->TupleInt_length-11379923615081194535\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-4148863126349750477:s->possible_values-13042725723116283049\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-13770179520251441998:s->Value_int-1870696621799859130\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-14757501459592564217:s->TupleValue___getitem__-14448359888109329694\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-14448359888109329694:s->Int___sub__-11477953740632672431\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-14448359888109329694:s->possible_values-12211324669098738792\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-2598150418935018079:s->Value_float-15173113486080567242\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-12107377412216353484:s->Value_float-6235596405652351031\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-3712217405396014230:s->sum-1955564354691009820\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_int-12938778466233897741:s->Int___init__-5871781006564002453\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-10864543514592368202:s->NDArray_vector-467762655970733886\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-10864543514592368202:s->TupleInt___init__-12938778466233897741\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-15769018209198649053:s->asarray-17776165865978447989\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-6690955771313385503:s->sum-1681433789052220133\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-16788298149597563309:s->NDArray_vector-18083105675662741245\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_dtype-15121139857639374588\n", + "\n", + "\n", + "NDArray_dtype\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_isfinite-10080759905092916392\n", + "\n", + "\n", + "assume_isfinite\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_dtype-10080759905092916392\n", + "\n", + "\n", + "NDArray_dtype\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_shape-14591484260056516843\n", + "\n", + "\n", + "assume_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_dtype-11743562013128004906\n", + "\n", + "\n", + "NDArray_dtype\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_dtype-3429551472952562336\n", + "\n", + "\n", + "assume_dtype(NDArray_var("X"), ·)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "DType_float64-0\n", + "\n", + "\n", + "DType_float64\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_device-15121139857639374588\n", + "\n", + "\n", + "NDArray_device\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "asarray-9510298863856844727\n", + "\n", + "\n", + "asarray(·, OptionalDType_none, OptionalBool_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float___truediv__-12808993487988576005\n", + "\n", + "\n", + "Float___truediv__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float_rational-0\n", + "\n", + "\n", + "Float_rational((rational 1 1))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float_from_int-11951456526892775522\n", + "\n", + "\n", + "Float_from_int\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float_rational-17615343019692007359\n", + "\n", + "\n", + "Float_rational((rational 1 999998))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float_from_int-12938778466233897741\n", + "\n", + "\n", + "Float_from_int\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt_length-11379923615081194535\n", + "\n", + "\n", + "TupleInt_length\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float___truediv__-5949890542083451333\n", + "\n", + "\n", + "Float___truediv__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float___init__-10858178701590265856\n", + "\n", + "\n", + "Float___init__(1.0)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float___init__-15726603433882419200\n", + "\n", + "\n", + "Float___init__(1000000.0)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float_rational-5871781006564002453\n", + "\n", + "\n", + "Float_rational((rational 1000000 1))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___sub__-2601583573127157282\n", + "\n", + "\n", + "Int___sub__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Float_rational-11743562013128004906\n", + "\n", + "\n", + "Float_rational((rational 999998 1))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-11068081844434038611\n", + "\n", + "\n", + "IndexKey_multi_axis\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-7546443524583315781\n", + "\n", + "\n", + "MultiAxisIndexKey___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-2961965818023366657\n", + "\n", + "\n", + "IndexKey_multi_axis\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-9019874688858188702\n", + "\n", + "\n", + "MultiAxisIndexKey___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_slice-4520820669176069863\n", + "\n", + "\n", + "IndexKey_slice\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Slice___init__-15501507093852132239\n", + "\n", + "\n", + "Slice___init__(OptionalInt_none, ·, OptionalInt_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-2650124047376210733\n", + "\n", + "\n", + "IndexKey_multi_axis\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-4155431249018709085\n", + "\n", + "\n", + "MultiAxisIndexKey___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-7690503999922668929\n", + "\n", + "\n", + "ndarray_index\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-17968234112188297122\n", + "\n", + "\n", + "NDArray___eq__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-3689419615158525606\n", + "\n", + "\n", + "IndexKey_multi_axis\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-10696952293987308628\n", + "\n", + "\n", + "MultiAxisIndexKey___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-10236680790416494354\n", + "\n", + "\n", + "ndarray_index\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-7887474207095380730\n", + "\n", + "\n", + "NDArray___eq__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-4468847040734877209\n", + "\n", + "\n", + "ndarray_index\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-3677844317228415595\n", + "\n", + "\n", + "NDArray___eq__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_int-12938778466233897741\n", + "\n", + "\n", + "IndexKey_int\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___sub__-11477953740632672431\n", + "\n", + "\n", + "Int___sub__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-9457253364840142751\n", + "\n", + "\n", + "ndarray_index\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-5948126446311695931\n", + "\n", + "\n", + "NDArray___eq__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray_index-1091269196223507527\n", + "\n", + "\n", + "ndarray_index\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___eq__-14314110614928331155\n", + "\n", + "\n", + "NDArray___eq__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "IndexKey_multi_axis-5456168980075999428\n", + "\n", + "\n", + "IndexKey_multi_axis\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___add__-8188473634840644445\n", + "\n", + "\n", + "MultiAxisIndexKey___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-16347205588787662656\n", + "\n", + "\n", + "Int___init__(1000000)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-11743562013128004906\n", + "\n", + "\n", + "Int___init__(2)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-4603643575659657750\n", + "\n", + "\n", + "Int___init__(999998)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-7742477628363861583\n", + "\n", + "\n", + "NDArray_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue_length-51973628441192654\n", + "\n", + "\n", + "TupleValue_length\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___init__-14757501459592564217\n", + "\n", + "\n", + "TupleValue___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue_length-883374682458736911\n", + "\n", + "\n", + "TupleValue_length\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___init__-3845340500482103568\n", + "\n", + "\n", + "TupleValue___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___add__-17495654355659155035\n", + "\n", + "\n", + "Int___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-5871781006564002453\n", + "\n", + "\n", + "Int___init__(1)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_to_int-7118971088111087942\n", + "\n", + "\n", + "Value_to_int\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_to_value-1247190081547085489\n", + "\n", + "\n", + "NDArray_to_value\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_to_int-5352221723193614120\n", + "\n", + "\n", + "Value_to_int\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_to_value-17927184790339163283\n", + "\n", + "\n", + "NDArray_to_value\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue_length-467762655970733886\n", + "\n", + "\n", + "TupleValue_length\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___add__-15259460202689358531\n", + "\n", + "\n", + "TupleValue___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue_length-18083105675662741245\n", + "\n", + "\n", + "TupleValue_length\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "possible_values-12211324669098738792\n", + "\n", + "\n", + "possible_values\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___getitem__-14078601210367663714\n", + "\n", + "\n", + "TupleInt___getitem__(·, Int___init__(0))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-12782857580910319779\n", + "\n", + "\n", + "NDArray_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___getitem__-11605336705429392564\n", + "\n", + "\n", + "TupleInt___getitem__(·, Int___init__(0))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-10080759905092916392\n", + "\n", + "\n", + "NDArray_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___getitem__-12686509587440430679\n", + "\n", + "\n", + "TupleInt___getitem__(·, Int___init__(0))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___init__-103947256882385308\n", + "\n", + "\n", + "TupleInt___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___getitem__-7967890718712059612\n", + "\n", + "\n", + "TupleInt___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___add__-13243224121832505654\n", + "\n", + "\n", + "TupleInt___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int___init__-6755155689022739364\n", + "\n", + "\n", + "Int___init__(20)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-9353306107957757443\n", + "\n", + "\n", + "MultiAxisIndexKey___init__(MultiAxisIndexKeyItem_slice(Slice___init__(OptionalInt_none, OptionalInt_none, OptionalInt_none)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-12159351040657546138\n", + "\n", + "\n", + "MultiAxisIndexKey___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-9665147878604913367\n", + "\n", + "\n", + "MultiAxisIndexKey___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_slice-6287570034093543685\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_slice\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-17771263905015585321\n", + "\n", + "\n", + "MultiAxisIndexKey___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_int-12938778466233897741\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_int\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-4312926155411299247\n", + "\n", + "\n", + "MultiAxisIndexKey___init__(MultiAxisIndexKeyItem_int(Int___init__(0)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKey___init__-10392601675740072316\n", + "\n", + "\n", + "MultiAxisIndexKey___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_slice-4520820669176069863\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_slice\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_slice-3793366872040910914\n", + "\n", + "\n", + "MultiAxisIndexKeyItem_slice\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Slice___init__-14445438978175812750\n", + "\n", + "\n", + "Slice___init__(OptionalInt_none, ·, OptionalInt_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Slice___init__-1162291712589082458\n", + "\n", + "\n", + "Slice___init__(OptionalInt_none, ·, OptionalInt_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-11120055472875231265\n", + "\n", + "\n", + "NDArray_scalar\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_float-5248274466311228812\n", + "\n", + "\n", + "Value_float\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "asarray-7902703286805427734\n", + "\n", + "\n", + "asarray(·, OptionalDType_none, OptionalBool_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-17483047916985507424\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-18325169333216085054\n", + "\n", + "\n", + "NDArray___setitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "mean-9206860573968271485\n", + "\n", + "\n", + "mean(·, ·, FALSE)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-16307929054953181812\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalIntOrTuple_some-6859102945905124672\n", + "\n", + "\n", + "OptionalIntOrTuple_some(IntOrTuple_int(Int___init__(0)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "concat-9071020324919791953\n", + "\n", + "\n", + "concat(·, OptionalInt_some(Int___init__(0)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___add__-17612194977553982959\n", + "\n", + "\n", + "TupleNDArray___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-18135092377765138894\n", + "\n", + "\n", + "TupleNDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "svd-7253966389981509278\n", + "\n", + "\n", + "svd(·, FALSE)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_T-2858018561140981349\n", + "\n", + "\n", + "NDArray_T\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-11279504549742320031\n", + "\n", + "\n", + "NDArray___truediv__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-18178625676753040942\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-11026489642259430172\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-7132500556515696557\n", + "\n", + "\n", + "NDArray___matmul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-15656725660214344740\n", + "\n", + "\n", + "NDArray___truediv__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "astype-6261542238027864055\n", + "\n", + "\n", + "astype\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-2598150418935018079\n", + "\n", + "\n", + "NDArray_scalar\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-9557034512502171054\n", + "\n", + "\n", + "NDArray___matmul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-9788377807842481490\n", + "\n", + "\n", + "NDArray___truediv__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-5767087113385015795\n", + "\n", + "\n", + "NDArray___setitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_T-10444575304181264970\n", + "\n", + "\n", + "NDArray_T\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-7696624279617524538\n", + "\n", + "\n", + "NDArray___mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-9914932780259612220\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-14757501459592564217\n", + "\n", + "\n", + "NDArray_scalar\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-9658389681233211557\n", + "\n", + "\n", + "TupleValue___getitem__(·, Int___init__(0))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-16424482750509214731\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "concat-430064524623572644\n", + "\n", + "\n", + "concat(·, OptionalInt_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___truediv__-3215265837560371319\n", + "\n", + "\n", + "NDArray___truediv__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-11494903289568215254\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-1818913068061409678\n", + "\n", + "\n", + "TupleNDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-2205987174022554874\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___gt__-15651908559655936539\n", + "\n", + "\n", + "NDArray___gt__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-1143242824664700181\n", + "\n", + "\n", + "NDArray_scalar(Value_float(Float___init__(0.0001)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___gt__-8664676620264668937\n", + "\n", + "\n", + "NDArray___gt__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-17539377729349800285\n", + "\n", + "\n", + "TupleNDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-8440009558605893705\n", + "\n", + "\n", + "NDArray___mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "asarray-17776165865978447989\n", + "\n", + "\n", + "asarray(·, OptionalDType_none, OptionalBool_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-3845340500482103568\n", + "\n", + "\n", + "NDArray_scalar\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "sum-1955564354691009820\n", + "\n", + "\n", + "sum(·, OptionalIntOrTuple_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "astype-14592420363448682842\n", + "\n", + "\n", + "astype(·, DType_int32)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-13476223401931994896\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_T-15484955256727723166\n", + "\n", + "\n", + "NDArray_T\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-15121139857639374588\n", + "\n", + "\n", + "NDArray_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___setitem__-7453141863274628760\n", + "\n", + "\n", + "NDArray___setitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "mean-3476503888447580293\n", + "\n", + "\n", + "mean(·, ·, FALSE)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-10680274783444675613\n", + "\n", + "\n", + "TupleNDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "astype-12468708834165933853\n", + "\n", + "\n", + "astype(·, DType_int32)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-15588902513610108474\n", + "\n", + "\n", + "NDArray_scalar\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-1182067134106770624\n", + "\n", + "\n", + "NDArray_index(·, TupleInt___init__(Int___init__(0)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-17758114586016463110\n", + "\n", + "\n", + "NDArray___getitem__(·, IndexKey_int(Int___init__(0)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_float-15173113486080567242\n", + "\n", + "\n", + "Value_float\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-3836913244690017957\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-10045558824545728354\n", + "\n", + "\n", + "TupleNDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-6343722845416298339\n", + "\n", + "\n", + "NDArray___getitem__(·, IndexKey_int(Int___init__(0)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-12107377412216353484\n", + "\n", + "\n", + "NDArray_scalar\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_float-6235596405652351031\n", + "\n", + "\n", + "Value_float\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "sum-1681433789052220133\n", + "\n", + "\n", + "sum(·, OptionalIntOrTuple_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-13392291772433010205\n", + "\n", + "\n", + "NDArray___matmul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-15957548086918070248\n", + "\n", + "\n", + "TupleNDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "reshape-4112525690760736104\n", + "\n", + "\n", + "reshape(·, TupleInt___init__(Int___init__(-1)), OptionalBool_none)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_value_one_of-5323778840018127892\n", + "\n", + "\n", + "assume_value_one_of\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "assume_shape-8316602628326787375\n", + "\n", + "\n", + "assume_shape(assume_dtype(NDArray_var("y"), DType_int64), ·)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "std-4851945112178408602\n", + "\n", + "\n", + "std\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "svd-2189404700831293460\n", + "\n", + "\n", + "svd(·, FALSE)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "unique_counts-7742477628363861583\n", + "\n", + "\n", + "unique_counts\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-8455018010728142919\n", + "\n", + "\n", + "NDArray___mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray-sqrt-4416873412293684555\n", + "\n", + "\n", + "ndarray-sqrt\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "zeros-16505489609336576318\n", + "\n", + "\n", + "zeros\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___add__-10752996994297486686\n", + "\n", + "\n", + "TupleInt___add__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalDType_some-3429551472952562336\n", + "\n", + "\n", + "OptionalDType_some\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalDevice_some-5144327209428843504\n", + "\n", + "\n", + "OptionalDevice_some\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_scalar-13770179520251441998\n", + "\n", + "\n", + "NDArray_scalar\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_int-1870696621799859130\n", + "\n", + "\n", + "Value_int\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___getitem__-9812641508136405718\n", + "\n", + "\n", + "NDArray___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-4099386548708531027\n", + "\n", + "\n", + "NDArray___mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_T-17147757364762811680\n", + "\n", + "\n", + "NDArray_T\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-1374586120005010617\n", + "\n", + "\n", + "NDArray___sub__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-8877293197236476153\n", + "\n", + "\n", + "NDArray___sub__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-9558798608273926456\n", + "\n", + "\n", + "NDArray___sub__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___matmul__-10968585808826125111\n", + "\n", + "\n", + "NDArray___matmul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "unique_inverse-7742477628363861583\n", + "\n", + "\n", + "unique_inverse\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "ndarray-sqrt-5404195351634806774\n", + "\n", + "\n", + "ndarray-sqrt\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___mul__-3756686807776082277\n", + "\n", + "\n", + "NDArray___mul__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray___sub__-10430407918099810154\n", + "\n", + "\n", + "NDArray___sub__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___init__-12782857580910319779\n", + "\n", + "\n", + "TupleNDArray___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___getitem__-13683004811263061306\n", + "\n", + "\n", + "TupleNDArray___getitem__(·, Int___init__(0))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "unique_values-12782857580910319779\n", + "\n", + "\n", + "unique_values\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_vector-18083105675662741245\n", + "\n", + "\n", + "NDArray_vector\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "unique_values-7742477628363861583\n", + "\n", + "\n", + "unique_values\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_vector-467762655970733886\n", + "\n", + "\n", + "NDArray_vector\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "possible_values-13042725723116283049\n", + "\n", + "\n", + "possible_values\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-1353837537593392198\n", + "\n", + "\n", + "TupleValue___getitem__(·, Int___init__(0))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___init__-1870696621799859130\n", + "\n", + "\n", + "TupleInt___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalInt_some-11224002729757616573\n", + "\n", + "\n", + "OptionalInt_some\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalInt_some-12938778466233897741\n", + "\n", + "\n", + "OptionalInt_some\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "OptionalInt_some-12990752094675090395\n", + "\n", + "\n", + "OptionalInt_some\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-7586556743040283621-value\n", + "\n", + "\n", + "(py-object -9223372036570011657 0)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-7586556743040283621\n", + "\n", + "\n", + "Int_to_py(Int___init__(0))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-11951456526892775522\n", + "\n", + "\n", + "Int_to_py\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-11951456526892775522-value\n", + "\n", + "\n", + "(py-object -9223372036570011657 999998)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-6079675520328773069\n", + "\n", + "\n", + "Int_to_py\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-6079675520328773069-value\n", + "\n", + "\n", + "(py-object -9223372036570011657 2)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-103947256882385308\n", + "\n", + "\n", + "Int_to_py\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-103947256882385308-value\n", + "\n", + "\n", + "(py-object -9223372036570011657 20)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-5092353580987650850-value\n", + "\n", + "\n", + "(py-object -9223372036570011657 -2)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-5092353580987650850\n", + "\n", + "\n", + "Int_to_py(Int___init__(-1))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-1870696621799859130\n", + "\n", + "\n", + "Int_to_py\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-1870696621799859130-value\n", + "\n", + "\n", + "(py-object -9223372036570011657 1000000)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Boolean_to_py-155920885323577962-value\n", + "\n", + "\n", + "(py-object 284764003 0)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Boolean_to_py-155920885323577962\n", + "\n", + "\n", + "Boolean_to_py(FALSE)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-12938778466233897741\n", + "\n", + "\n", + "Int_to_py\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Int_to_py-12938778466233897741-value\n", + "\n", + "\n", + "(py-object -9223372036570011657 1)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_shape-1714775736476281168\n", + "\n", + "\n", + "NDArray_shape\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___init__-6079675520328773069\n", + "\n", + "\n", + "TupleInt___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleInt___init__-12938778466233897741\n", + "\n", + "\n", + "TupleInt___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___init__-14497633317386600947\n", + "\n", + "\n", + "TupleNDArray___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleNDArray___init__-6131649148769965723\n", + "\n", + "\n", + "TupleNDArray___init__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-7786309113067083429\n", + "\n", + "\n", + "TupleValue___getitem__(·, Int___init__(0))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-12579319251068649370\n", + "\n", + "\n", + "NDArray_index(·, ALL_INDICES)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-17067340853146132798\n", + "\n", + "\n", + "NDArray_index(·, ALL_INDICES)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-4148863126349750477\n", + "\n", + "\n", + "TupleValue___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-1143242824664700181-value\n", + "\n", + "\n", + "()\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-1143242824664700181\n", + "\n", + "\n", + "greater_zero(Value_float(Float___init__(0.0001)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-13770179520251441998\n", + "\n", + "\n", + "greater_zero\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-13770179520251441998-value\n", + "\n", + "\n", + "()\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-14757501459592564217\n", + "\n", + "\n", + "greater_zero\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "TupleValue___getitem__-14448359888109329694\n", + "\n", + "\n", + "TupleValue___getitem__\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-14757501459592564217-value\n", + "\n", + "\n", + "()\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-2598150418935018079\n", + "\n", + "\n", + "greater_zero\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-2598150418935018079-value\n", + "\n", + "\n", + "()\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-12107377412216353484\n", + "\n", + "\n", + "greater_zero\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "greater_zero-12107377412216353484-value\n", + "\n", + "\n", + "()\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-3712217405396014230\n", + "\n", + "\n", + "NDArray_index(·, TupleInt_EMPTY)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_int-12938778466233897741\n", + "\n", + "\n", + "Value_int\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-10864543514592368202\n", + "\n", + "\n", + "NDArray_index\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-15769018209198649053\n", + "\n", + "\n", + "NDArray_index(·, ALL_INDICES)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-5822399466274154604\n", + "\n", + "\n", + "NDArray_index(assume_dtype(NDArray_var("y"), DType_int64), ALL_INDICES)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-7547271516962905184\n", + "\n", + "\n", + "NDArray_index(NDArray_var("y"), ALL_INDICES)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-6690955771313385503\n", + "\n", + "\n", + "NDArray_index(·, TupleInt_EMPTY)\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "NDArray_index-16788298149597563309\n", + "\n", + "\n", + "NDArray_index(·, TupleInt___init__(Int___init__(0)))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "Value_int-7586556743040283621\n", + "\n", + "\n", + "Value_int(Int___init__(0))\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "" ], - "source": [ - "import numba\n", - "import os\n", - "\n", - "fn_numba = numba.njit(fastmath=True)(fn)\n", - "assert np.allclose(run_lda(X_np, y_np), fn_numba(X_np, y_np))" - ] - }, - { - "cell_type": "markdown", - "id": "078d41b3", - "metadata": {}, - "source": [ - "## Evaluating performance\n", - "\n", - "Let's see if it actually made anything quicker! Let's run a number of trials for the original function, our\n", - "extracted version, and the optimized extracted version:\n" + "text/plain": [ + "" ] - }, + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "egraph.display(n_inline_leaves=3, split_primitive_outputs=True)" + ] + }, + { + "cell_type": "markdown", + "id": "21e4ee3a", + "metadata": {}, + "source": [ + "## Translating for Numba\n", + "\n", + "We are getting closer to a form we could translate back to Numba, but we have to make a few changes. Numba doesn't\n", + "support the `axis` keyword for `mean` or `std`, but it does support it for `sum`, so we have to translate all forms\n", + "from one to the other, with a rule like this (defined in [`egglog.exp.array_api_numba`](https://github.com/egraphs-good/egglog-python/blob/main/python/egglog/exp/array_api_numba.py)):\n", + "\n", + "```python\n", + "axis = OptionalIntOrTuple.some(IntOrTuple.int(i))\n", + "rewrite(std(x, axis)).to(sqrt(mean(square(abs(x - mean(x, axis, keepdims=TRUE))), axis)))\n", + "```\n", + "\n", + "We can run those additional rewrites now to get a new extracted version\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "9e79f88e", + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 10, - "id": "27a0cafc", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
originalextractedextracted numba
01.4829751.6093541.086486
11.4986561.5047041.145331
21.5009981.5572531.090356
31.5197321.5488001.122623
41.5004201.5011951.113089
51.5872111.5225181.176842
61.4994791.5268871.095296
71.6399101.5008591.086477
81.5251451.5592021.103662
91.5356011.4742991.074152
\n", - "
" - ], - "text/plain": [ - " original extracted extracted numba\n", - "0 1.482975 1.609354 1.086486\n", - "1 1.498656 1.504704 1.145331\n", - "2 1.500998 1.557253 1.090356\n", - "3 1.519732 1.548800 1.122623\n", - "4 1.500420 1.501195 1.113089\n", - "5 1.587211 1.522518 1.176842\n", - "6 1.499479 1.526887 1.095296\n", - "7 1.639910 1.500859 1.086477\n", - "8 1.525145 1.559202 1.103662\n", - "9 1.535601 1.474299 1.074152" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } + "data": { + "text/html": [ + "
_NDArray_1 = NDArray.var("X")\n",
+       "assume_dtype(_NDArray_1, DType.float64)\n",
+       "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n",
+       "assume_isfinite(_NDArray_1)\n",
+       "_NDArray_2 = NDArray.var("y")\n",
+       "assume_dtype(_NDArray_2, DType.int64)\n",
+       "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n",
+       "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n",
+       "_NDArray_3 = astype(\n",
+       "    NDArray.vector(TupleValue(sum(_NDArray_2 == NDArray.scalar(Value.int(Int(0)))).to_value()) + TupleValue(sum(_NDArray_2 == NDArray.scalar(Value.int(Int(1)))).to_value())),\n",
+       "    DType.float64,\n",
+       ") / NDArray.scalar(Value.float(Float(1000000.0)))\n",
+       "_NDArray_4 = zeros(TupleInt(Int(2)) + TupleInt(Int(20)), OptionalDType.some(DType.float64), OptionalDevice.some(_NDArray_1.device))\n",
+       "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n",
+       "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n",
+       "_NDArray_5 = _NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(0))))]\n",
+       "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n",
+       "_NDArray_4[_IndexKey_1] = sum(_NDArray_5, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_5.shape[Int(0)]))\n",
+       "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n",
+       "_NDArray_6 = _NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(1))))]\n",
+       "_NDArray_4[_IndexKey_2] = sum(_NDArray_6, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_6.shape[Int(0)]))\n",
+       "_NDArray_7 = concat(TupleNDArray(_NDArray_5 - _NDArray_4[_IndexKey_1]) + TupleNDArray(_NDArray_6 - _NDArray_4[_IndexKey_2]), OptionalInt.some(Int(0)))\n",
+       "_NDArray_8 = square(_NDArray_7 - expand_dims(sum(_NDArray_7, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_7.shape[Int(0)]))))\n",
+       "_NDArray_9 = sqrt(sum(_NDArray_8, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_8.shape[Int(0)])))\n",
+       "_NDArray_10 = copy(_NDArray_9)\n",
+       "_NDArray_10[ndarray_index(_NDArray_9 == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n",
+       "_TupleNDArray_1 = svd(sqrt(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(Int(999998))))) * (_NDArray_7 / _NDArray_10), FALSE)\n",
+       "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n",
+       "_NDArray_11 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_10).T / _TupleNDArray_1[\n",
+       "    Int(1)\n",
+       "][IndexKey.slice(_Slice_1)]\n",
+       "_TupleNDArray_2 = svd(\n",
+       "    (sqrt((NDArray.scalar(Value.int(Int(1000000))) * _NDArray_3) * NDArray.scalar(Value.float(Float(1.0)))) * (_NDArray_4 - (_NDArray_3 @ _NDArray_4)).T).T @ _NDArray_11, FALSE\n",
+       ")\n",
+       "(\n",
+       "    (_NDArray_1 - (_NDArray_3 @ _NDArray_4))\n",
+       "    @ (\n",
+       "        _NDArray_11\n",
+       "        @ _TupleNDArray_2[Int(2)].T[\n",
+       "            IndexKey.multi_axis(\n",
+       "                _MultiAxisIndexKey_1\n",
+       "                + MultiAxisIndexKey(\n",
+       "                    MultiAxisIndexKeyItem.slice(\n",
+       "                        Slice(\n",
+       "                            OptionalInt.none,\n",
+       "                            OptionalInt.some(\n",
+       "                                sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n",
+       "                                .to_value()\n",
+       "                                .to_int\n",
+       "                            ),\n",
+       "                        )\n",
+       "                    )\n",
+       "                )\n",
+       "            )\n",
+       "        ]\n",
+       "    )\n",
+       ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(Int(1))))))]\n",
+       "
\n" ], - "source": [ - "import timeit\n", - "import pandas as pd\n", - "\n", - "stmts = {\n", - " \"original\": \"run_lda(X_np, y_np)\",\n", - " \"extracted\": \"fn(X_np, y_np)\",\n", - " \"extracted numba\": \"fn_numba(X_np, y_np)\",\n", - "}\n", - "df = pd.DataFrame.from_dict(\n", - " {name: timeit.repeat(stmt, globals=globals(), number=1, repeat=10) for name, stmt in stmts.items()}\n", - ")\n", - "\n", - "df" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "9488c513", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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4403zJYtW8z48eNNYmKiue6663z7DBo0yPz617/2LXft2tUkJyebuXPnmu3bt5uZM2eaqKgo8+WXX/r2+cMf/mDWrFljSkpKzFtvvWVSUlLMI4884tt+ah04dw899JC58MILzbvvvmuKi4vNc889Z1wul8nPzze7du0ybdq0MbNnzzbGGHPjjTeaAQMGmGPHjpnjx4+b119/3UgyW7duNWVlZebgwYPGmBPvfXx8vJk6dar58ssvfe/xrFmzzLJly0xJSYn58MMPTc+ePc2dd97pq2Xjxo3G5XKZO++80xQUFJjPP//cPPnkk+abb74xBw8eNJdffrm5/fbbTVlZmSkrKzPHjx83Bw4cMO3atTO5ublmy5YtZsOGDWbo0KEmKyvL97x33nmn6dKli/nggw/MZ599Zq699lqTkJBQ6/MZrhp6/4wxEf0eTps2zcTHx5sbbrjBbN682axcudKkpqaa//iP//Dt07VrVzNr1qxax2VkZJhp06b5liWZTp06mb/+9a9m69atZvjw4SYtLc0MGTLEvPvuu+aLL74wl112mbnqqqtqvXZcXJwZMmSI2bhxo1mxYoXp3r27GTVqlG+fDz/80OTl5ZktW7aYL774wowbN86kpKQYr9fbyHe/aQjqMFFZWWlatmxpXnzxRd+6o0ePmo4dO5pHH33UF9RLliypddypAZmSkmL+9Kc/+ZaPHz9uunTpcsagHj16tG+5pqbGtG/f3jz99NP11vunP/3JZGZm1lsHzs33339vYmNjzUcffVRr/bhx48zIkSONMca88sorplWrVua+++4zcXFxZtu2bb79Tn5eDhw4UOv4QYMGmX79+p3x9V999VXTtm1b3/LIkSPNwIED693/1M+UMSf+uLvyyitrrdu5c6cvfA4dOmRiYmLMK6+84tu+f/9+07p167AP6sa8f8ZE7ns4bdo0ExsbWyv4pk6dai699FLfcmOD+v777/ctf/zxx0aSeeaZZ3zrXnrpJdOqVatarx0dHW127drlW/fOO++YqKgoU1ZWVme91dXVJiEhwfzv//5vvT/TueAcdZgoLi7WsWPHNHDgQN+6li1basCAAdqyZYsuueQSSVL//v3rfY6KigqVl5drwIABvnXR0dHKzMxUTU1Ng6/fp08f378dx1Fqaqr27t3rW/fXv/5VTzzxhIqLi1VZWanjx49zAf4A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3nqr1jGFhYW69tprlZiYqISEBP3kJz9RcXGxpk+frueff15vvvmmHMeR4zjKz8+vs+t7xYoVGjBggFwulzp06KD77rtPx48f920fPHiwJk2apN/+9rdKTk5WampqrTqBSEVQA83EnDlz9OCDD6pz584qKyurdd/xM5kxY4ZGjBihzz77TNdcc41uueUWffvtt5Kk3bt366c//alcLpeWLVum9evXa+zYsTp+/LimTJmiESNG6KqrrlJZWZnKysrqbM3v3r1b11xzjS655BJt2rRJTz/9tJ555hk99NBDtfZ7/vnnFRcXp7Vr1+rRRx/Vgw8+qPfff//cfjFAmKPrG2gm3G63EhISzqrbecyYMRo5cqQk6eGHH9YTTzyhTz75RFdddZXmzp0rt9utl19+WS1btpQkpaen+45t3bq1qqqqGnzNefPmyePx6KmnnpLjOLrwwgv19ddf695779UDDzzguz9xnz59NG3aNEkn7vn71FNP6cMPP9TQoUOb9PMAzQktagDq06eP799xcXFKTEzU3r17JUkFBQX6yU9+4gvps7FlyxZdfvnlchzHt27gwIGqrKzUrl276qxDkjp06OCrA4hUBDXQjEVFRenUiR3Hjh07bb9TQ9hxHNXU1Eg60WIOlobqACIVQQ00Y+3atVNZWZlv2ev1qqSkpEnP0adPH61atarOgJekmJgYVVdXN/gcvXr10scff1zrj4Y1a9YoISFBnTt3blI9QKQhqIFmbMiQIcrLy9OqVau0efNm5eTkKDo6uknPcdddd8nr9ermm2/WunXrtH37duXl5Wnr1q2SpLS0NH322WfaunWr9u3bV2egT5gwQTt37tTdd9+tL7/8Um+++aamTZumyZMn+85PA6gb/0OAZiw3N1eDBg3Stddeq1/84hcaPny4unXr1qTnaNu2rZYtW6bKykoNGjRImZmZ+u///m9fN/Xtt9+unj17qn///mrXrp3WrFlz2nN06tRJb7/9tj755BNlZGRo/PjxGjdunO6//36//JxAc8aVyQAAsBgtagAALEZQAwBgMYIaAACLEdQAAFiMoAYAwGIENQAAFiOoAQCwGEENAIDFCGoAACxGUAMAYDGCGgAAixHUAABY7P8B0daK/soSNGUAAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } + "text/latex": [ + "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{X}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}isfinite}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{var}\\PY{p}{(}\\PY{l+s+s2}{\\PYZdq{}}\\PY{l+s+s2}{y}\\PY{l+s+s2}{\\PYZdq{}}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}dtype}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int64}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}shape}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{assume\\PYZus{}value\\PYZus{}one\\PYZus{}of}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2}\\PY{p}{,} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{=} \\PY{n}{astype}\\PY{p}{(}\n", + " \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{vector}\\PY{p}{(}\\PY{n}{TupleValue}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleValue}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,}\n", + " \\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{,}\n", + "\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1000000.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{=} \\PY{n}{zeros}\\PY{p}{(}\\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleInt}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{20}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalDType}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{DType}\\PY{o}{.}\\PY{n}{float64}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalDevice}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{o}{.}\\PY{n}{device}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{=} \\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", + "\\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1} \\PY{o}{=} \\PY{n}{OptionalIntOrTuple}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{IntOrTuple}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]} \\PY{o}{=} \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2} \\PY{o}{=} \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}6} \\PY{o}{=} \\PY{n}{\\PYZus{}NDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}2} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]} \\PY{o}{=} \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{=} \\PY{n}{concat}\\PY{p}{(}\\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}5} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}1}\\PY{p}{]}\\PY{p}{)} \\PY{o}{+} \\PY{n}{TupleNDArray}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}6} \\PY{o}{\\PYZhy{}} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{[}\\PY{n}{\\PYZus{}IndexKey\\PYZus{}2}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}8} \\PY{o}{=} \\PY{n}{square}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{\\PYZhy{}} \\PY{n}{expand\\PYZus{}dims}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}9} \\PY{o}{=} \\PY{n}{sqrt}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{p}{,} \\PY{n}{\\PYZus{}OptionalIntOrTuple\\PYZus{}1}\\PY{p}{)} \\PY{o}{/} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}8}\\PY{o}{.}\\PY{n}{shape}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}10} \\PY{o}{=} \\PY{n}{copy}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}9}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}10}\\PY{p}{[}\\PY{n}{ndarray\\PYZus{}index}\\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}9} \\PY{o}{==} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]} \\PY{o}{=} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\\PY{n}{sqrt}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)} \\PY{o}{/} \\PY{n}{Float}\\PY{o}{.}\\PY{n}{from\\PYZus{}int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{999998}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}7} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}10}\\PY{p}{)}\\PY{p}{,} \\PY{n}{FALSE}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}Slice\\PYZus{}1} \\PY{o}{=} \\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\\PY{o}{.}\\PY{n}{to\\PYZus{}int}\\PY{p}{)}\\PY{p}{)}\n", + "\\PY{n}{\\PYZus{}NDArray\\PYZus{}11} \\PY{o}{=} \\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{)} \\PY{o}{+} \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{/} \\PY{n}{\\PYZus{}NDArray\\PYZus{}10}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{/} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}1}\\PY{p}{[}\n", + " \\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\n", + "\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{\\PYZus{}Slice\\PYZus{}1}\\PY{p}{)}\\PY{p}{]}\n", + "\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2} \\PY{o}{=} \\PY{n}{svd}\\PY{p}{(}\n", + " \\PY{p}{(}\\PY{n}{sqrt}\\PY{p}{(}\\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1000000}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}NDArray\\PYZus{}3}\\PY{p}{)} \\PY{o}{*} \\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{1.0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}4} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T}\\PY{p}{)}\\PY{o}{.}\\PY{n}{T} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}11}\\PY{p}{,} \\PY{n}{FALSE}\n", + "\\PY{p}{)}\n", + "\\PY{p}{(}\n", + " \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}1} \\PY{o}{\\PYZhy{}} \\PY{p}{(}\\PY{n}{\\PYZus{}NDArray\\PYZus{}3} \\PY{o}{@} \\PY{n}{\\PYZus{}NDArray\\PYZus{}4}\\PY{p}{)}\\PY{p}{)}\n", + " \\PY{o}{@} \\PY{p}{(}\n", + " \\PY{n}{\\PYZus{}NDArray\\PYZus{}11}\n", + " \\PY{o}{@} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{]}\\PY{o}{.}\\PY{n}{T}\\PY{p}{[}\n", + " \\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\n", + " \\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1}\n", + " \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\n", + " \\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\n", + " \\PY{n}{Slice}\\PY{p}{(}\n", + " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,}\n", + " \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\n", + " \\PY{n+nb}{sum}\\PY{p}{(}\\PY{n}{astype}\\PY{p}{(}\\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]} \\PY{o}{\\PYZgt{}} \\PY{p}{(}\\PY{n}{NDArray}\\PY{o}{.}\\PY{n}{scalar}\\PY{p}{(}\\PY{n}{Value}\\PY{o}{.}\\PY{n}{float}\\PY{p}{(}\\PY{n}{Float}\\PY{p}{(}\\PY{l+m+mf}{0.0001}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)} \\PY{o}{*} \\PY{n}{\\PYZus{}TupleNDArray\\PYZus{}2}\\PY{p}{[}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{]}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{int}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\\PY{p}{)}\\PY{p}{,} \\PY{n}{DType}\\PY{o}{.}\\PY{n}{int32}\\PY{p}{)}\\PY{p}{)}\n", + " \\PY{o}{.}\\PY{n}{to\\PYZus{}value}\\PY{p}{(}\\PY{p}{)}\n", + " \\PY{o}{.}\\PY{n}{to\\PYZus{}int}\n", + " \\PY{p}{)}\\PY{p}{,}\n", + " \\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{p}{)}\n", + " \\PY{p}{]}\n", + " \\PY{p}{)}\n", + "\\PY{p}{)}\\PY{p}{[}\\PY{n}{IndexKey}\\PY{o}{.}\\PY{n}{multi\\PYZus{}axis}\\PY{p}{(}\\PY{n}{\\PYZus{}MultiAxisIndexKey\\PYZus{}1} \\PY{o}{+} \\PY{n}{MultiAxisIndexKey}\\PY{p}{(}\\PY{n}{MultiAxisIndexKeyItem}\\PY{o}{.}\\PY{n}{slice}\\PY{p}{(}\\PY{n}{Slice}\\PY{p}{(}\\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{none}\\PY{p}{,} \\PY{n}{OptionalInt}\\PY{o}{.}\\PY{n}{some}\\PY{p}{(}\\PY{n}{Int}\\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{)}\\PY{p}{]}\n", + "\\end{Verbatim}\n" ], - "source": [ - "import seaborn as sns\n", - "\n", - "df_melt = pd.melt(df, var_name=\"function\", value_name=\"time\")\n", - "_ = sns.catplot(data=df_melt, x=\"function\", y=\"time\", kind=\"swarm\")" + "text/plain": [ + "_NDArray_1 = NDArray.var(\"X\")\n", + "assume_dtype(_NDArray_1, DType.float64)\n", + "assume_shape(_NDArray_1, TupleInt(Int(1000000)) + TupleInt(Int(20)))\n", + "assume_isfinite(_NDArray_1)\n", + "_NDArray_2 = NDArray.var(\"y\")\n", + "assume_dtype(_NDArray_2, DType.int64)\n", + "assume_shape(_NDArray_2, TupleInt(Int(1000000)))\n", + "assume_value_one_of(_NDArray_2, TupleValue(Value.int(Int(0))) + TupleValue(Value.int(Int(1))))\n", + "_NDArray_3 = astype(\n", + " NDArray.vector(TupleValue(sum(_NDArray_2 == NDArray.scalar(Value.int(Int(0)))).to_value()) + TupleValue(sum(_NDArray_2 == NDArray.scalar(Value.int(Int(1)))).to_value())),\n", + " DType.float64,\n", + ") / NDArray.scalar(Value.float(Float(1000000.0)))\n", + "_NDArray_4 = zeros(TupleInt(Int(2)) + TupleInt(Int(20)), OptionalDType.some(DType.float64), OptionalDevice.some(_NDArray_1.device))\n", + "_MultiAxisIndexKey_1 = MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice()))\n", + "_IndexKey_1 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(0))) + _MultiAxisIndexKey_1)\n", + "_NDArray_5 = _NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(0))))]\n", + "_OptionalIntOrTuple_1 = OptionalIntOrTuple.some(IntOrTuple.int(Int(0)))\n", + "_NDArray_4[_IndexKey_1] = sum(_NDArray_5, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_5.shape[Int(0)]))\n", + "_IndexKey_2 = IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.int(Int(1))) + _MultiAxisIndexKey_1)\n", + "_NDArray_6 = _NDArray_1[ndarray_index(_NDArray_2 == NDArray.scalar(Value.int(Int(1))))]\n", + "_NDArray_4[_IndexKey_2] = sum(_NDArray_6, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_6.shape[Int(0)]))\n", + "_NDArray_7 = concat(TupleNDArray(_NDArray_5 - _NDArray_4[_IndexKey_1]) + TupleNDArray(_NDArray_6 - _NDArray_4[_IndexKey_2]), OptionalInt.some(Int(0)))\n", + "_NDArray_8 = square(_NDArray_7 - expand_dims(sum(_NDArray_7, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_7.shape[Int(0)]))))\n", + "_NDArray_9 = sqrt(sum(_NDArray_8, _OptionalIntOrTuple_1) / NDArray.scalar(Value.int(_NDArray_8.shape[Int(0)])))\n", + "_NDArray_10 = copy(_NDArray_9)\n", + "_NDArray_10[ndarray_index(_NDArray_9 == NDArray.scalar(Value.int(Int(0))))] = NDArray.scalar(Value.float(Float(1.0)))\n", + "_TupleNDArray_1 = svd(sqrt(NDArray.scalar(Value.float(Float(1.0) / Float.from_int(Int(999998))))) * (_NDArray_7 / _NDArray_10), FALSE)\n", + "_Slice_1 = Slice(OptionalInt.none, OptionalInt.some(sum(astype(_TupleNDArray_1[Int(1)] > NDArray.scalar(Value.float(Float(0.0001))), DType.int32)).to_value().to_int))\n", + "_NDArray_11 = (_TupleNDArray_1[Int(2)][IndexKey.multi_axis(MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(_Slice_1)) + _MultiAxisIndexKey_1)] / _NDArray_10).T / _TupleNDArray_1[\n", + " Int(1)\n", + "][IndexKey.slice(_Slice_1)]\n", + "_TupleNDArray_2 = svd(\n", + " (sqrt((NDArray.scalar(Value.int(Int(1000000))) * _NDArray_3) * NDArray.scalar(Value.float(Float(1.0)))) * (_NDArray_4 - (_NDArray_3 @ _NDArray_4)).T).T @ _NDArray_11, FALSE\n", + ")\n", + "(\n", + " (_NDArray_1 - (_NDArray_3 @ _NDArray_4))\n", + " @ (\n", + " _NDArray_11\n", + " @ _TupleNDArray_2[Int(2)].T[\n", + " IndexKey.multi_axis(\n", + " _MultiAxisIndexKey_1\n", + " + MultiAxisIndexKey(\n", + " MultiAxisIndexKeyItem.slice(\n", + " Slice(\n", + " OptionalInt.none,\n", + " OptionalInt.some(\n", + " sum(astype(_TupleNDArray_2[Int(1)] > (NDArray.scalar(Value.float(Float(0.0001))) * _TupleNDArray_2[Int(1)][IndexKey.int(Int(0))]), DType.int32))\n", + " .to_value()\n", + " .to_int\n", + " ),\n", + " )\n", + " )\n", + " )\n", + " )\n", + " ]\n", + " )\n", + ")[IndexKey.multi_axis(_MultiAxisIndexKey_1 + MultiAxisIndexKey(MultiAxisIndexKeyItem.slice(Slice(OptionalInt.none, OptionalInt.some(Int(1))))))]" ] - }, + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from egglog.exp.array_api_numba import array_api_numba_module\n", + "\n", + "egraph = EGraph([array_api_numba_module])\n", + "egraph.register(X_r2_optimized)\n", + "egraph.run(10000)\n", + "X_r2_numba = egraph.extract(X_r2_optimized)\n", + "X_r2_numba" + ] + }, + { + "cell_type": "markdown", + "id": "969490bb", + "metadata": {}, + "source": [ + "## Compiling back to Python source\n", + "\n", + "Now we finally have a version that we could run with Numba! However, this isn't in NumPy code. What Numba needs\n", + "is a function that uses `numpy`, not our typed dialect.\n", + "\n", + "So we use another module that provides a translation of all our methods into Python strings. The rules in it look like this:\n", + "\n", + "```python\n", + "# the sqrt of an array should use the `np.sqrt` function and be assigned to its own variable, so it can be reused\n", + "rewrite(ndarray_program(sqrt(x))).to((Program(\"np.sqrt(\") + ndarray_program(x) + \")\").assign())\n", + "\n", + "# To compile a setitem call, we first compile the source, assign it to a variable, then add an assignment statement\n", + "mod_x = copy(x)\n", + "mod_x[idx] = y\n", + "assigned_x = ndarray_program(x).assign()\n", + "yield rewrite(ndarray_program(mod_x)).to(\n", + " assigned_x.statement(assigned_x + \"[\" + index_key_program(idx) + \"] = \" + ndarray_program(y))\n", + ")\n", + "```\n", + "\n", + "We pull in all those rewrite rules from the [`egglog.exp.array_api_program_gen` module](https://github.com/egraphs-good/egglog-python/blob/main/python/egglog/exp/array_api_program_gen.py).\n", + "They depend on another module, [`egglog.exp.program_gen` module](https://github.com/egraphs-good/egglog-python/blob/main/python/egglog/exp/program_gen.py), which provides generic translations\n", + "from expressions and statements into strings.\n", + "\n", + "We can run these rules to get out a Python function object:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "3aeae673", + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "id": "83eab582", - "metadata": {}, - "source": [ - "We see that the numba version is in fact faster, and the other two are about the same. It isn't significantly faster through,\n", - "so we might want to run a profiler on the original function to see where most of the time is spent:\n" - ] - }, + "name": "stdout", + "output_type": "stream", + "text": [ + "def __fn(X, y):\n", + " assert X.dtype == np.dtype(np.float64)\n", + " assert X.shape == (1000000, 20,)\n", + " assert np.all(np.isfinite(X))\n", + " assert y.dtype == np.dtype(np.int64)\n", + " assert y.shape == (1000000,)\n", + " assert set(np.unique(y)) == set((0, 1,))\n", + " _0 = y == np.array(0)\n", + " _1 = np.sum(_0)\n", + " _2 = y == np.array(1)\n", + " _3 = np.sum(_2)\n", + " _4 = np.array((_1, _3,)).astype(np.dtype(np.float64))\n", + " _5 = _4 / np.array(1000000.0)\n", + " _6 = np.zeros((2, 20,), dtype=np.dtype(np.float64))\n", + " _7 = np.sum(X[_0], axis=0)\n", + " _8 = _7 / np.array(X[_0].shape[0])\n", + " _6[0, :] = _8\n", + " _9 = np.sum(X[_2], axis=0)\n", + " _10 = _9 / np.array(X[_2].shape[0])\n", + " _6[1, :] = _10\n", + " _11 = _5 @ _6\n", + " _12 = X - _11\n", + " _13 = np.sqrt(np.array((1.0 / 999998)))\n", + " _14 = X[_0] - _6[0, :]\n", + " _15 = X[_2] - _6[1, :]\n", + " _16 = np.concatenate((_14, _15,), axis=0)\n", + " _17 = np.sum(_16, axis=0)\n", + " _18 = _17 / np.array(_16.shape[0])\n", + " _19 = np.expand_dims(_18, 0)\n", + " _20 = _16 - _19\n", + " _21 = np.square(_20)\n", + " _22 = np.sum(_21, axis=0)\n", + " _23 = _22 / np.array(_21.shape[0])\n", + " _24 = np.sqrt(_23)\n", + " _25 = _24 == np.array(0)\n", + " _24[_25] = np.array(1.0)\n", + " _26 = _16 / _24\n", + " _27 = _13 * _26\n", + " _28 = np.linalg.svd(_27, full_matrices=False)\n", + " _29 = _28[1] > np.array(0.0001)\n", + " _30 = _29.astype(np.dtype(np.int32))\n", + " _31 = np.sum(_30)\n", + " _32 = _28[2][:_31, :] / _24\n", + " _33 = _32.T / _28[1][:_31]\n", + " _34 = np.array(1000000) * _5\n", + " _35 = _34 * np.array(1.0)\n", + " _36 = np.sqrt(_35)\n", + " _37 = _6 - _11\n", + " _38 = _36 * _37.T\n", + " _39 = _38.T @ _33\n", + " _40 = np.linalg.svd(_39, full_matrices=False)\n", + " _41 = np.array(0.0001) * _40[1][0]\n", + " _42 = _40[1] > _41\n", + " _43 = _42.astype(np.dtype(np.int32))\n", + " _44 = np.sum(_43)\n", + " _45 = _33 @ _40[2].T[:, :_44]\n", + " _46 = _12 @ _45\n", + " return _46[:, :1]\n", + "\n" + ] + } + ], + "source": [ + "from egglog.exp.array_api_program_gen import (\n", + " array_api_module_string,\n", + " ndarray_function_two,\n", + ")\n", + "\n", + "egraph = EGraph([array_api_module_string])\n", + "fn_program = ndarray_function_two(X_r2_numba, X_orig, y_orig)\n", + "egraph.register(fn_program)\n", + "egraph.run(10000)\n", + "fn = egraph.load_object(egraph.extract(fn_program.py_object))\n", + "import inspect\n", + "\n", + "print(inspect.getsource(fn))" + ] + }, + { + "cell_type": "markdown", + "id": "6e0405c8", + "metadata": {}, + "source": [ + "We can verify that the function gives the same result:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "a807d66c", + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "\n", + "assert np.allclose(run_lda(X_np, y_np), fn(X_np, y_np))" + ] + }, + { + "cell_type": "markdown", + "id": "b2a3f1ed", + "metadata": {}, + "source": [ + "Although it isn't the prettiest, we can see that it has only emitted each expression once, for common subexpression\n", + "elimination, and preserves the \"imperative\" aspects of setitem.\n", + "\n", + "## Compiling to Numba\n", + "\n", + "Now we finally have a function we can run with numba:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "39a69f23", + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 12, - "id": "06d7777a", - "metadata": {}, - "outputs": [], - "source": [ - "%load_ext line_profiler" - ] - }, + "name": "stderr", + "output_type": "stream", + "text": [ + "/var/folders/xn/05ktz3056kqd9n8frgd6236h0000gn/T/egglog-9e61d62c-d17d-495b-b8db-f1eb3b38dcbb.py:56: NumbaPerformanceWarning: '@' is faster on contiguous arrays, called on (Array(float64, 2, 'C', False, aligned=True), Array(float64, 2, 'A', False, aligned=True))\n", + " _45 = _33 @ _40[2].T[:, :_44]\n" + ] + } + ], + "source": [ + "import numba\n", + "\n", + "fn_numba = numba.njit(fastmath=True)(fn)\n", + "assert np.allclose(run_lda(X_np, y_np), fn_numba(X_np, y_np))" + ] + }, + { + "cell_type": "markdown", + "id": "078d41b3", + "metadata": {}, + "source": [ + "## Evaluating performance\n", + "\n", + "Let's see if it actually made anything quicker! Let's run a number of trials for the original function, our\n", + "extracted version, and the optimized extracted version:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "27a0cafc", + "metadata": {}, + "outputs": [ { - "cell_type": "code", - "execution_count": 13, - "id": "f88942d6", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Timer unit: 1e-09 s\n", - "\n", - "Total time: 1.41607 s\n", - "File: /var/folders/xn/05ktz3056kqd9n8frgd6236h0000gn/T/egglog-9e61d62c-d17d-495b-b8db-f1eb3b38dcbb.py\n", - "Function: __fn at line 1\n", - "\n", - "Line # Hits Time Per Hit % Time Line Contents\n", - "==============================================================\n", - " 1 def __fn(X, y):\n", - " 2 1 13000.0 13000.0 0.0 assert X.dtype == np.dtype(np.float64)\n", - " 3 1 2000.0 2000.0 0.0 assert X.shape == (1000000, 20,)\n", - " 4 1 23813000.0 2e+07 1.7 assert np.all(np.isfinite(X))\n", - " 5 1 11000.0 11000.0 0.0 assert y.dtype == np.dtype(np.int64)\n", - " 6 1 14000.0 14000.0 0.0 assert y.shape == (1000000,)\n", - " 7 1 23226000.0 2e+07 1.6 assert set(np.unique(y)) == set((0, 1,))\n", - " 8 1 542000.0 542000.0 0.0 _0 = y == np.array(0)\n", - " 9 1 488000.0 488000.0 0.0 _1 = np.sum(_0)\n", - " 10 1 493000.0 493000.0 0.0 _2 = y == np.array(1)\n", - " 11 1 454000.0 454000.0 0.0 _3 = np.sum(_2)\n", - " 12 1 14000.0 14000.0 0.0 _4 = np.array((_1, _3,)).astype(np.dtype(np.float64))\n", - " 13 1 9000.0 9000.0 0.0 _5 = _4 / np.array(1000000.0)\n", - " 14 1 4000.0 4000.0 0.0 _6 = np.zeros((2, 20,), dtype=np.dtype(np.float64))\n", - " 15 1 98376000.0 1e+08 6.9 _7 = np.sum(X[_0], axis=0)\n", - " 16 1 38374000.0 4e+07 2.7 _8 = _7 / np.array(X[_0].shape[0])\n", - " 17 1 6000.0 6000.0 0.0 _6[0, :] = _8\n", - " 18 1 45697000.0 5e+07 3.2 _9 = np.sum(X[_2], axis=0)\n", - " 19 1 35522000.0 4e+07 2.5 _10 = _9 / np.array(X[_2].shape[0])\n", - " 20 1 6000.0 6000.0 0.0 _6[1, :] = _10\n", - " 21 1 13000.0 13000.0 0.0 _11 = _5 @ _6\n", - " 22 1 33768000.0 3e+07 2.4 _12 = X - _11\n", - " 23 1 18000.0 18000.0 0.0 _13 = np.sqrt(np.array((1.0 / 999998)))\n", - " 24 1 50544000.0 5e+07 3.6 _14 = X[_0] - _6[0, :]\n", - " 25 1 55966000.0 6e+07 4.0 _15 = X[_2] - _6[1, :]\n", - " 26 1 26138000.0 3e+07 1.8 _16 = np.concatenate((_14, _15,), axis=0)\n", - " 27 1 23667000.0 2e+07 1.7 _17 = np.sum(_16, axis=0)\n", - " 28 1 26000.0 26000.0 0.0 _18 = _17 / np.array(_16.shape[0])\n", - " 29 1 45000.0 45000.0 0.0 _19 = np.expand_dims(_18, 0)\n", - " 30 1 33604000.0 3e+07 2.4 _20 = _16 - _19\n", - " 31 1 24774000.0 2e+07 1.7 _21 = np.square(_20)\n", - " 32 1 21671000.0 2e+07 1.5 _22 = np.sum(_21, axis=0)\n", - " 33 1 31000.0 31000.0 0.0 _23 = _22 / np.array(_21.shape[0])\n", - " 34 1 4000.0 4000.0 0.0 _24 = np.sqrt(_23)\n", - " 35 1 7000.0 7000.0 0.0 _25 = _24 == np.array(0)\n", - " 36 1 3000.0 3000.0 0.0 _24[_25] = np.array(1.0)\n", - " 37 1 32910000.0 3e+07 2.3 _26 = _16 / _24\n", - " 38 1 24105000.0 2e+07 1.7 _27 = _13 * _26\n", - " 39 1 814200000.0 8e+08 57.5 _28 = np.linalg.svd(_27, full_matrices=False)\n", - " 40 1 23000.0 23000.0 0.0 _29 = _28[1] > np.array(0.0001)\n", - " 41 1 10000.0 10000.0 0.0 _30 = _29.astype(np.dtype(np.int32))\n", - " 42 1 63000.0 63000.0 0.0 _31 = np.sum(_30)\n", - " 43 1 14000.0 14000.0 0.0 _32 = _28[2][:_31, :] / _24\n", - " 44 1 7000.0 7000.0 0.0 _33 = _32.T / _28[1][:_31]\n", - " 45 1 9000.0 9000.0 0.0 _34 = np.array(1000000) * _5\n", - " 46 1 4000.0 4000.0 0.0 _35 = _34 * np.array(1.0)\n", - " 47 1 3000.0 3000.0 0.0 _36 = np.sqrt(_35)\n", - " 48 1 5000.0 5000.0 0.0 _37 = _6 - _11\n", - " 49 1 4000.0 4000.0 0.0 _38 = _36 * _37.T\n", - " 50 1 11000.0 11000.0 0.0 _39 = _38.T @ _33\n", - " 51 1 70000.0 70000.0 0.0 _40 = np.linalg.svd(_39, full_matrices=False)\n", - " 52 1 6000.0 6000.0 0.0 _41 = np.array(0.0001) * _40[1][0]\n", - " 53 1 3000.0 3000.0 0.0 _42 = _40[1] > _41\n", - " 54 1 4000.0 4000.0 0.0 _43 = _42.astype(np.dtype(np.int32))\n", - " 55 1 18000.0 18000.0 0.0 _44 = np.sum(_43)\n", - " 56 1 8000.0 8000.0 0.0 _45 = _33 @ _40[2].T[:, :_44]\n", - " 57 1 7242000.0 7e+06 0.5 _46 = _12 @ _45\n", - " 58 1 7000.0 7000.0 0.0 return _46[:, :1]" - ] - } + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
originalextractedextracted numba
01.4829751.6093541.086486
11.4986561.5047041.145331
21.5009981.5572531.090356
31.5197321.5488001.122623
41.5004201.5011951.113089
51.5872111.5225181.176842
61.4994791.5268871.095296
71.6399101.5008591.086477
81.5251451.5592021.103662
91.5356011.4742991.074152
\n", + "
" ], - "source": [ - "%lprun -f fn fn(X_np, y_np)" + "text/plain": [ + " original extracted extracted numba\n", + "0 1.482975 1.609354 1.086486\n", + "1 1.498656 1.504704 1.145331\n", + "2 1.500998 1.557253 1.090356\n", + "3 1.519732 1.548800 1.122623\n", + "4 1.500420 1.501195 1.113089\n", + "5 1.587211 1.522518 1.176842\n", + "6 1.499479 1.526887 1.095296\n", + "7 1.639910 1.500859 1.086477\n", + "8 1.525145 1.559202 1.103662\n", + "9 1.535601 1.474299 1.074152" ] - }, + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import timeit\n", + "\n", + "import pandas as pd\n", + "\n", + "stmts = {\n", + " \"original\": \"run_lda(X_np, y_np)\",\n", + " \"extracted\": \"fn(X_np, y_np)\",\n", + " \"extracted numba\": \"fn_numba(X_np, y_np)\",\n", + "}\n", + "df = pd.DataFrame.from_dict({\n", + " name: timeit.repeat(stmt, globals=globals(), number=1, repeat=10) for name, stmt in stmts.items()\n", + "})\n", + "\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "9488c513", + "metadata": {}, + "outputs": [ { - "cell_type": "markdown", - "id": "7bf27fb6", - "metadata": {}, - "source": [ - "We see that most of the time is spent in the SVD funciton, which [wouldn't be improved much by numba](https://github.com/numba/numba/issues/2423)\n", - "since it is will call out to LAPACK, just like NumPy. The only savings would come from the other parts of the progarm,\n", - "which can be inlined into\n", - "\n", - "## Conclusion\n", - "\n", - "To recap, in this tutorial we:\n", - "\n", - "1. Tried using a normal scikit-learn LDA function on some test data.\n", - "2. Built up an abstract array and called it with that instead\n", - "3. Optimized it and translated it to work with Numba\n", - "4. Compiled it to a standalone Python funciton, which was optimized with Numba\n", - "5. Verified that this improved our performance with this test data.\n", - "\n", - "The implementation of the Array API provided here is experimental, and not complete, but at least serves to show it is\n", - "possible to build an API like that with `egglog`.\n" + "data": { + "image/png": "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4403zJYtW8z48eNNYmKiue6663z7DBo0yPz617/2LXft2tUkJyebuXPnmu3bt5uZM2eaqKgo8+WXX/r2+cMf/mDWrFljSkpKzFtvvWVSUlLMI4884tt+ah04dw899JC58MILzbvvvmuKi4vNc889Z1wul8nPzze7du0ybdq0MbNnzzbGGHPjjTeaAQMGmGPHjpnjx4+b119/3UgyW7duNWVlZebgwYPGmBPvfXx8vJk6dar58ssvfe/xrFmzzLJly0xJSYn58MMPTc+ePc2dd97pq2Xjxo3G5XKZO++80xQUFJjPP//cPPnkk+abb74xBw8eNJdffrm5/fbbTVlZmSkrKzPHjx83Bw4cMO3atTO5ublmy5YtZsOGDWbo0KEmKyvL97x33nmn6dKli/nggw/MZ599Zq699lqTkJBQ6/MZrhp6/4wxEf0eTps2zcTHx5sbbrjBbN682axcudKkpqaa//iP//Dt07VrVzNr1qxax2VkZJhp06b5liWZTp06mb/+9a9m69atZvjw4SYtLc0MGTLEvPvuu+aLL74wl112mbnqqqtqvXZcXJwZMmSI2bhxo1mxYoXp3r27GTVqlG+fDz/80OTl5ZktW7aYL774wowbN86kpKQYr9fbyHe/aQjqMFFZWWlatmxpXnzxRd+6o0ePmo4dO5pHH33UF9RLliypddypAZmSkmL+9Kc/+ZaPHz9uunTpcsagHj16tG+5pqbGtG/f3jz99NP11vunP/3JZGZm1lsHzs33339vYmNjzUcffVRr/bhx48zIkSONMca88sorplWrVua+++4zcXFxZtu2bb79Tn5eDhw4UOv4QYMGmX79+p3x9V999VXTtm1b3/LIkSPNwIED693/1M+UMSf+uLvyyitrrdu5c6cvfA4dOmRiYmLMK6+84tu+f/9+07p167AP6sa8f8ZE7ns4bdo0ExsbWyv4pk6dai699FLfcmOD+v777/ctf/zxx0aSeeaZZ3zrXnrpJdOqVatarx0dHW127drlW/fOO++YqKgoU1ZWVme91dXVJiEhwfzv//5vvT/TueAcdZgoLi7WsWPHNHDgQN+6li1basCAAdqyZYsuueQSSVL//v3rfY6KigqVl5drwIABvnXR0dHKzMxUTU1Ng6/fp08f378dx1Fqaqr27t3rW/fXv/5VTzzxhIqLi1VZWanjx49zAf4A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3nqr1jGFhYW69tprlZiYqISEBP3kJz9RcXGxpk+frueff15vvvmmHMeR4zjKz8+vs+t7xYoVGjBggFwulzp06KD77rtPx48f920fPHiwJk2apN/+9rdKTk5WampqrTqBSEVQA83EnDlz9OCDD6pz584qKyurdd/xM5kxY4ZGjBihzz77TNdcc41uueUWffvtt5Kk3bt366c//alcLpeWLVum9evXa+zYsTp+/LimTJmiESNG6KqrrlJZWZnKysrqbM3v3r1b11xzjS655BJt2rRJTz/9tJ555hk99NBDtfZ7/vnnFRcXp7Vr1+rRRx/Vgw8+qPfff//cfjFAmKPrG2gm3G63EhISzqrbecyYMRo5cqQk6eGHH9YTTzyhTz75RFdddZXmzp0rt9utl19+WS1btpQkpaen+45t3bq1qqqqGnzNefPmyePx6KmnnpLjOLrwwgv19ddf695779UDDzzguz9xnz59NG3aNEkn7vn71FNP6cMPP9TQoUOb9PMAzQktagDq06eP799xcXFKTEzU3r17JUkFBQX6yU9+4gvps7FlyxZdfvnlchzHt27gwIGqrKzUrl276qxDkjp06OCrA4hUBDXQjEVFRenUiR3Hjh07bb9TQ9hxHNXU1Eg60WIOlobqACIVQQ00Y+3atVNZWZlv2ev1qqSkpEnP0adPH61atarOgJekmJgYVVdXN/gcvXr10scff1zrj4Y1a9YoISFBnTt3blI9QKQhqIFmbMiQIcrLy9OqVau0efNm5eTkKDo6uknPcdddd8nr9ermm2/WunXrtH37duXl5Wnr1q2SpLS0NH322WfaunWr9u3bV2egT5gwQTt37tTdd9+tL7/8Um+++aamTZumyZMn+85PA6gb/0OAZiw3N1eDBg3Stddeq1/84hcaPny4unXr1qTnaNu2rZYtW6bKykoNGjRImZmZ+u///m9fN/Xtt9+unj17qn///mrXrp3WrFlz2nN06tRJb7/9tj755BNlZGRo/PjxGjdunO6//36//JxAc8aVyQAAsBgtagAALEZQAwBgMYIaAACLEdQAAFiMoAYAwGIENQAAFiOoAQCwGEENAIDFCGoAACxGUAMAYDGCGgAAixHUAABY7P8B0daK/soSNGUAAAAASUVORK5CYII=", + "text/plain": [ + "
" ] + }, + "metadata": {}, + "output_type": "display_data" } - ], - "metadata": { - "file_format": "mystnb", - "kernelspec": { - "display_name": "egglog-python", - "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.10.12" - }, - "mystnb": { - "execution_mode": "off" + ], + "source": [ + "import seaborn as sns\n", + "\n", + "df_melt = pd.melt(df, var_name=\"function\", value_name=\"time\")\n", + "_ = sns.catplot(data=df_melt, x=\"function\", y=\"time\", kind=\"swarm\")" + ] + }, + { + "cell_type": "markdown", + "id": "83eab582", + "metadata": {}, + "source": [ + "We see that the numba version is in fact faster, and the other two are about the same. It isn't significantly faster through,\n", + "so we might want to run a profiler on the original function to see where most of the time is spent:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "06d7777a", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext line_profiler" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "f88942d6", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Timer unit: 1e-09 s\n", + "\n", + "Total time: 1.41607 s\n", + "File: /var/folders/xn/05ktz3056kqd9n8frgd6236h0000gn/T/egglog-9e61d62c-d17d-495b-b8db-f1eb3b38dcbb.py\n", + "Function: __fn at line 1\n", + "\n", + "Line # Hits Time Per Hit % Time Line Contents\n", + "==============================================================\n", + " 1 def __fn(X, y):\n", + " 2 1 13000.0 13000.0 0.0 assert X.dtype == np.dtype(np.float64)\n", + " 3 1 2000.0 2000.0 0.0 assert X.shape == (1000000, 20,)\n", + " 4 1 23813000.0 2e+07 1.7 assert np.all(np.isfinite(X))\n", + " 5 1 11000.0 11000.0 0.0 assert y.dtype == np.dtype(np.int64)\n", + " 6 1 14000.0 14000.0 0.0 assert y.shape == (1000000,)\n", + " 7 1 23226000.0 2e+07 1.6 assert set(np.unique(y)) == set((0, 1,))\n", + " 8 1 542000.0 542000.0 0.0 _0 = y == np.array(0)\n", + " 9 1 488000.0 488000.0 0.0 _1 = np.sum(_0)\n", + " 10 1 493000.0 493000.0 0.0 _2 = y == np.array(1)\n", + " 11 1 454000.0 454000.0 0.0 _3 = np.sum(_2)\n", + " 12 1 14000.0 14000.0 0.0 _4 = np.array((_1, _3,)).astype(np.dtype(np.float64))\n", + " 13 1 9000.0 9000.0 0.0 _5 = _4 / np.array(1000000.0)\n", + " 14 1 4000.0 4000.0 0.0 _6 = np.zeros((2, 20,), dtype=np.dtype(np.float64))\n", + " 15 1 98376000.0 1e+08 6.9 _7 = np.sum(X[_0], axis=0)\n", + " 16 1 38374000.0 4e+07 2.7 _8 = _7 / np.array(X[_0].shape[0])\n", + " 17 1 6000.0 6000.0 0.0 _6[0, :] = _8\n", + " 18 1 45697000.0 5e+07 3.2 _9 = np.sum(X[_2], axis=0)\n", + " 19 1 35522000.0 4e+07 2.5 _10 = _9 / np.array(X[_2].shape[0])\n", + " 20 1 6000.0 6000.0 0.0 _6[1, :] = _10\n", + " 21 1 13000.0 13000.0 0.0 _11 = _5 @ _6\n", + " 22 1 33768000.0 3e+07 2.4 _12 = X - _11\n", + " 23 1 18000.0 18000.0 0.0 _13 = np.sqrt(np.array((1.0 / 999998)))\n", + " 24 1 50544000.0 5e+07 3.6 _14 = X[_0] - _6[0, :]\n", + " 25 1 55966000.0 6e+07 4.0 _15 = X[_2] - _6[1, :]\n", + " 26 1 26138000.0 3e+07 1.8 _16 = np.concatenate((_14, _15,), axis=0)\n", + " 27 1 23667000.0 2e+07 1.7 _17 = np.sum(_16, axis=0)\n", + " 28 1 26000.0 26000.0 0.0 _18 = _17 / np.array(_16.shape[0])\n", + " 29 1 45000.0 45000.0 0.0 _19 = np.expand_dims(_18, 0)\n", + " 30 1 33604000.0 3e+07 2.4 _20 = _16 - _19\n", + " 31 1 24774000.0 2e+07 1.7 _21 = np.square(_20)\n", + " 32 1 21671000.0 2e+07 1.5 _22 = np.sum(_21, axis=0)\n", + " 33 1 31000.0 31000.0 0.0 _23 = _22 / np.array(_21.shape[0])\n", + " 34 1 4000.0 4000.0 0.0 _24 = np.sqrt(_23)\n", + " 35 1 7000.0 7000.0 0.0 _25 = _24 == np.array(0)\n", + " 36 1 3000.0 3000.0 0.0 _24[_25] = np.array(1.0)\n", + " 37 1 32910000.0 3e+07 2.3 _26 = _16 / _24\n", + " 38 1 24105000.0 2e+07 1.7 _27 = _13 * _26\n", + " 39 1 814200000.0 8e+08 57.5 _28 = np.linalg.svd(_27, full_matrices=False)\n", + " 40 1 23000.0 23000.0 0.0 _29 = _28[1] > np.array(0.0001)\n", + " 41 1 10000.0 10000.0 0.0 _30 = _29.astype(np.dtype(np.int32))\n", + " 42 1 63000.0 63000.0 0.0 _31 = np.sum(_30)\n", + " 43 1 14000.0 14000.0 0.0 _32 = _28[2][:_31, :] / _24\n", + " 44 1 7000.0 7000.0 0.0 _33 = _32.T / _28[1][:_31]\n", + " 45 1 9000.0 9000.0 0.0 _34 = np.array(1000000) * _5\n", + " 46 1 4000.0 4000.0 0.0 _35 = _34 * np.array(1.0)\n", + " 47 1 3000.0 3000.0 0.0 _36 = np.sqrt(_35)\n", + " 48 1 5000.0 5000.0 0.0 _37 = _6 - _11\n", + " 49 1 4000.0 4000.0 0.0 _38 = _36 * _37.T\n", + " 50 1 11000.0 11000.0 0.0 _39 = _38.T @ _33\n", + " 51 1 70000.0 70000.0 0.0 _40 = np.linalg.svd(_39, full_matrices=False)\n", + " 52 1 6000.0 6000.0 0.0 _41 = np.array(0.0001) * _40[1][0]\n", + " 53 1 3000.0 3000.0 0.0 _42 = _40[1] > _41\n", + " 54 1 4000.0 4000.0 0.0 _43 = _42.astype(np.dtype(np.int32))\n", + " 55 1 18000.0 18000.0 0.0 _44 = np.sum(_43)\n", + " 56 1 8000.0 8000.0 0.0 _45 = _33 @ _40[2].T[:, :_44]\n", + " 57 1 7242000.0 7e+06 0.5 _46 = _12 @ _45\n", + " 58 1 7000.0 7000.0 0.0 return _46[:, :1]" + ] } + ], + "source": [ + "%lprun -f fn fn(X_np, y_np)" + ] + }, + { + "cell_type": "markdown", + "id": "7bf27fb6", + "metadata": {}, + "source": [ + "We see that most of the time is spent in the SVD funciton, which [wouldn't be improved much by numba](https://github.com/numba/numba/issues/2423)\n", + "since it is will call out to LAPACK, just like NumPy. The only savings would come from the other parts of the progarm,\n", + "which can be inlined into\n", + "\n", + "## Conclusion\n", + "\n", + "To recap, in this tutorial we:\n", + "\n", + "1. Tried using a normal scikit-learn LDA function on some test data.\n", + "2. Built up an abstract array and called it with that instead\n", + "3. Optimized it and translated it to work with Numba\n", + "4. Compiled it to a standalone Python funciton, which was optimized with Numba\n", + "5. Verified that this improved our performance with this test data.\n", + "\n", + "The implementation of the Array API provided here is experimental, and not complete, but at least serves to show it is\n", + "possible to build an API like that with `egglog`.\n" + ] + } + ], + "metadata": { + "file_format": "mystnb", + "kernelspec": { + "display_name": "egglog-python", + "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.10.12" }, - "nbformat": 4, - "nbformat_minor": 5 + "mystnb": { + "execution_mode": "off" + } + }, + "nbformat": 4, + "nbformat_minor": 5 } diff --git a/python/tests/conftest.py b/python/tests/conftest.py index e50a1f56..c96b391f 100644 --- a/python/tests/conftest.py +++ b/python/tests/conftest.py @@ -22,6 +22,6 @@ def serialize(self, data, **kwargs) -> bytes: return str(data).encode() -@pytest.fixture() +@pytest.fixture def snapshot_py(snapshot): return snapshot.with_defaults(extension_class=PythonSnapshotExtension)