{"id":22954981,"url":"https://github.com/hpac/matchpy","last_synced_at":"2025-04-05T06:02:34.029Z","repository":{"id":47518064,"uuid":"66550798","full_name":"HPAC/matchpy","owner":"HPAC","description":"A library for pattern matching on symbolic expressions in Python.","archived":false,"fork":false,"pushed_at":"2024-04-18T09:07:37.000Z","size":926,"stargazers_count":168,"open_issues_count":18,"forks_count":25,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-29T05:02:04.604Z","etag":null,"topics":["pattern-matching","python","symbolic-expressions","term-rewriting"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/HPAC.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-08-25T11:04:59.000Z","updated_at":"2025-03-25T05:42:18.000Z","dependencies_parsed_at":"2024-06-18T21:30:42.086Z","dependency_job_id":"0c759994-7be5-4732-9deb-6828becbfd92","html_url":"https://github.com/HPAC/matchpy","commit_stats":{"total_commits":408,"total_committers":10,"mean_commits":40.8,"dds":"0.21323529411764708","last_synced_commit":"45f63748f4f57ed1803df09d2bfc4c7b28008995"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HPAC%2Fmatchpy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HPAC%2Fmatchpy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HPAC%2Fmatchpy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HPAC%2Fmatchpy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HPAC","download_url":"https://codeload.github.com/HPAC/matchpy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294514,"owners_count":20915340,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pattern-matching","python","symbolic-expressions","term-rewriting"],"created_at":"2024-12-14T16:20:26.502Z","updated_at":"2025-04-05T06:02:34.009Z","avatar_url":"https://github.com/HPAC.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"MatchPy\n=======\n\nMatchPy is a library for pattern matching on symbolic expressions in Python.\n\n**Work in progress**\n\n|pypi| |conda| |coverage| |build| |docs| |joss| |doi|\n\nInstallation\n------------\n\nMatchPy is available via `PyPI \u003chttps://pypi.python.org/pypi/matchpy\u003e`_, and for Conda via `conda-forge \u003chttps://anaconda.org/conda-forge/matchpy\u003e`_. It can be installed with ``pip install matchpy`` or ``conda install -c conda-forge matchpy``.\n\nOverview\n--------\n\nThis package implements `pattern matching \u003chttps://en.wikipedia.org/wiki/Pattern_matching\u003e`_ in Python. Pattern matching is a powerful tool for symbolic computations, operating on symbolic expressions. Given a pattern and an expression (which is usually called *subject*), the goal of pattern matching is to find a substitution for all the variables in the pattern such that the pattern becomes the subject. As an example, consider the pattern ``f(x)``, where ``f`` is a function and ``x`` is a variable, and the subject ``f(a)``, where ``a`` is a constant symbol. Then the substitution that replaces ``x`` with ``a`` is a match. MatchPy supports associative and/or commutative function symbols, as well as sequence variables, similar to pattern matching in `Mathematica \u003chttps://reference.wolfram.com/language/guide/Patterns.html\u003e`_. \n\nA detailed example of how to use MatchPy can be found `here \u003chttps://matchpy.readthedocs.io/en/latest/example.html\u003e`_.\n\nMatchPy supports both one-to-one and many-to-one pattern matching. The latter makes use of similarities between patterns to efficiently find matches for multiple patterns at the same time.\n\nA list of publications about MatchPy can be found `below \u003cPublications_\u003e`_.\n\nExpressions\n...........\n\nExpressions are tree-like data structures, consisting of operations (functions, internal nodes) and symbols (constants, leaves):\n\n\u003e\u003e\u003e from matchpy import Operation, Symbol, Arity\n\u003e\u003e\u003e f = Operation.new('f', Arity.binary)\n\u003e\u003e\u003e a = Symbol('a')\n\u003e\u003e\u003e print(f(a, a))\nf(a, a)\n\nPatterns are expressions which may contain wildcards (variables):\n\n\u003e\u003e\u003e from matchpy import Pattern, Wildcard\n\u003e\u003e\u003e x = Wildcard.dot('x')\n\u003e\u003e\u003e print(Pattern(f(a, x)))\nf(a, x_)\n\nIn the previous example, ``x`` is the name of the variable. However, it is also possible to use wildcards without names:\n\n\u003e\u003e\u003e w = Wildcard.dot()\n\u003e\u003e\u003e print(Pattern(f(w, w)))\nf(_, _)\n\nIt is also possible to assign variable names to entire subexpressions:\n\n\u003e\u003e\u003e print(Pattern(f(w, a, variable_name='y')))\ny: f(_, a)\n\nPattern Matching\n................\n\nGiven a pattern and an expression (which is usually called subject), the idea of pattern matching is to find a substitution that maps wildcards to expressions such that the pattern becomes the subject. In MatchPy, a substitution is a dict that maps variable names to expressions.\n\n\u003e\u003e\u003e from matchpy import match\n\u003e\u003e\u003e y = Wildcard.dot('y')\n\u003e\u003e\u003e b = Symbol('b')\n\u003e\u003e\u003e subject = f(a, b)\n\u003e\u003e\u003e pattern = Pattern(f(x, y))\n\u003e\u003e\u003e substitution = next(match(subject, pattern))\n\u003e\u003e\u003e print(substitution)\n{x ↦ a, y ↦ b}\n\nApplying the substitution to the pattern results in the original expression.\n\n\u003e\u003e\u003e from matchpy import substitute\n\u003e\u003e\u003e print(substitute(pattern, substitution))\nf(a, b)\n\nSequence Wildcards\n..................\n\nSequence wildcards are wildcards that can match a sequence of expressions instead of just a single expression:\n\n\u003e\u003e\u003e z = Wildcard.plus('z')\n\u003e\u003e\u003e pattern = Pattern(f(z))\n\u003e\u003e\u003e subject = f(a, b)\n\u003e\u003e\u003e substitution = next(match(subject, pattern))\n\u003e\u003e\u003e print(substitution)\n{z ↦ (a, b)}\n\nAssociativity and Commutativity\n...............................\n\nMatchPy natively supports associative and/or commutative operations. Nested associative operators are automatically flattened, the operands in commutative operations are sorted:\n\n\u003e\u003e\u003e g = Operation.new('g', Arity.polyadic, associative=True, commutative=True)\n\u003e\u003e\u003e print(g(a, g(b, a)))\ng(a, a, b)\n\nAssociativity and commutativity is also considered for pattern matching:\n\n\u003e\u003e\u003e pattern = Pattern(g(b, x))\n\u003e\u003e\u003e subject = g(a, a, b)\n\u003e\u003e\u003e print(next(match(subject, pattern)))\n{x ↦ g(a, a)}\n\u003e\u003e\u003e h = Operation.new('h', Arity.polyadic)\n\u003e\u003e\u003e pattern = Pattern(h(b, x))\n\u003e\u003e\u003e subject = h(a, a, b)\n\u003e\u003e\u003e list(match(subject, pattern))\n[]\n\nMany-to-One Matching\n....................\n\nWhen a fixed set of patterns is matched repeatedly against different subjects, matching can be sped up significantly by using many-to-one matching. The idea of many-to-one matching is to construct a so called discrimination net, a data structure similar to a decision tree or a finite automaton that exploits similarities between patterns. In MatchPy, there are two such data structures, implemented as classes: `DiscriminationNet \u003chttps://matchpy.readthedocs.io/en/latest/api/matchpy.matching.syntactic.html\u003e`_ and `ManyToOneMatcher \u003chttps://matchpy.readthedocs.io/en/latest/api/matchpy.matching.many_to_one.html\u003e`_. The DiscriminationNet class only supports syntactic pattern matching, that is, operations are neither associative nor commutative. Sequence variables are not supported either. The ManyToOneMatcher class supports associative and/or commutative matching with sequence variables. For syntactic pattern matching, the DiscriminationNet should be used, as it is usually faster.\n\n\u003e\u003e\u003e pattern1 = Pattern(f(a, x))\n\u003e\u003e\u003e pattern2 = Pattern(f(y, b))\n\u003e\u003e\u003e matcher = ManyToOneMatcher(pattern1, pattern2)\n\u003e\u003e\u003e subject = f(a, b)\n\u003e\u003e\u003e matches = matcher.match(subject)\n\u003e\u003e\u003e for matched_pattern, substitution in sorted(map(lambda m: (str(m[0]), str(m[1])), matches)):\n...     print('{} matched with {}'.format(matched_pattern, substitution))\nf(a, x_) matched with {x ↦ b}\nf(y_, b) matched with {y ↦ a}\n\nRoadmap\n-------\n\nBesides the existing features, we plan on adding the following to MatchPy:\n\n- Support for Mathematica's ``Alternatives``: For example ``f(a | b)`` would match either ``f(a)`` or ``f(b)``.\n- Support for Mathematica's ``Repeated``: For example ``f(a..)`` would match ``f(a)``, ``f(a, a)``, ``f(a, a, a)``, etc.\n- Support pattern sequences (``PatternSequence`` in Mathematica). These are mainly useful in combination with\n  ``Alternatives`` or ``Repeated``, e.g. ``f(a | (b, c))`` would match either ``f(a)`` or ``f(b, c)``.\n  ``f((a a)..)`` would match any ``f`` with an even number of ``a`` arguments.\n- All these additional pattern features need to be supported in the ``ManyToOneMatcher`` as well.\n- Better integration with existing types such as ``dict``.\n- Code generation for both one-to-one and many-to-one matching. There is already an experimental implementation, but it still has some dependencies on MatchPy which can probably be removed.\n- Improving the documentation with more examples.\n- Better test coverage with more randomized tests.\n- Implementation of the matching algorithms in a lower-level language, for example C, both for performance and to make MatchPy's functionality available in other languages.\n\nContributing\n------------\n\nIf you have some issue or want to contribute, please feel free to open an issue or create a pull request. Help is always appreciated!\n\nThe Makefile has several tasks to help development:\n\n- To install all needed packages, you can use ``make init`` .\n- To run the tests you can use ``make test``. The tests use `pytest \u003chttps://docs.pytest.org/\u003e`_.\n- To generate the documentation you can use ``make docs`` .\n- To run the style checker (`pylint \u003chttps://www.pylint.org/\u003e`_) you can use ``make check`` .\n\nIf you have any questions or need help with setting things up, please open an issue and we will try the best to assist you.\n\nPublications\n------------\n\n| `MatchPy: Pattern Matching in Python \u003chttp://joss.theoj.org/papers/10.21105/joss.00670\u003e`_\n| Manuel Krebber and Henrik Barthels\n| Journal of Open Source Software, Volume 3(26), pp. 2, June 2018.\n|\n\n| `Efficient Pattern Matching in Python \u003chttps://dl.acm.org/citation.cfm?id=3149871\u003e`_\n| Manuel Krebber, Henrik Barthels and Paolo Bientinesi\n| Proceedings of the 7th Workshop on Python for High-Performance and Scientific Computing, November 2017.\n|\n\n| `MatchPy: A Pattern Matching Library \u003chttp://conference.scipy.org/proceedings/scipy2017/manuel_krebber.html\u003e`_\n| Manuel Krebber, Henrik Barthels and Paolo Bientinesi\n| Proceedings of the 15th Python in Science Conference, July 2017.\n|\n\n| `Non-linear Associative-Commutative Many-to-One Pattern Matching with Sequence Variables \u003chttps://arxiv.org/abs/1705.00907\u003e`_\n| Manuel Krebber\n| Master Thesis, RWTH Aachen University, May 2017\n|\n\nIf you want to cite MatchPy, please reference the JOSS paper::\n\n    @article{krebber2018,\n        author    = {Manuel Krebber and Henrik Barthels},\n        title     = {{M}atch{P}y: {P}attern {M}atching in {P}ython},\n        journal   = {Journal of Open Source Software},\n        year      = 2018,\n        pages     = 2,\n        month     = jun,\n        volume    = {3},\n        number    = {26},\n        doi       = \"10.21105/joss.00670\",\n        web       = \"http://joss.theoj.org/papers/10.21105/joss.00670\",\n    }\n\n.. |pypi| image:: https://img.shields.io/pypi/v/matchpy.svg?style=flat\n    :target: https://pypi.org/project/matchpy/\n    :alt: Latest version released on PyPi\n\n.. |conda| image:: https://img.shields.io/conda/vn/conda-forge/matchpy.svg\n    :target: https://anaconda.org/conda-forge/matchpy\n    :alt: Latest version released via conda-forge\n\n.. |coverage| image:: https://coveralls.io/repos/github/HPAC/matchpy/badge.svg?branch=master\n    :target: https://coveralls.io/github/HPAC/matchpy?branch=master\n    :alt: Test coverage\n\n.. |build| image:: https://travis-ci.org/HPAC/matchpy.svg?branch=master\n    :target: https://travis-ci.org/HPAC/matchpy\n    :alt: Build status of the master branch\n\n.. |docs| image:: https://readthedocs.org/projects/matchpy/badge/?version=latest\n    :target: https://matchpy.readthedocs.io/en/latest/?badge=latest\n    :alt: Documentation Status\n    \n.. |joss| image:: http://joss.theoj.org/papers/e456bc05880b533652980aee6550a3cb/status.svg\n    :target: http://joss.theoj.org/papers/e456bc05880b533652980aee6550a3cb\n    :alt: The Journal of Open Source Software\n    \n.. |doi| image:: https://zenodo.org/badge/DOI/10.5281/zenodo.1294930.svg\n   :target: https://doi.org/10.5281/zenodo.1294930\n   :alt: Digital Object Identifier\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhpac%2Fmatchpy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhpac%2Fmatchpy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhpac%2Fmatchpy/lists"}