{"id":22589588,"url":"https://github.com/rhennigan/codeequivalenceutilities","last_synced_at":"2026-01-30T19:04:41.273Z","repository":{"id":38023438,"uuid":"415070270","full_name":"rhennigan/CodeEquivalenceUtilities","owner":"rhennigan","description":"Utilities for testing code equivalence","archived":false,"fork":false,"pushed_at":"2024-06-25T19:48:33.000Z","size":3338,"stargazers_count":7,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-05T15:05:01.974Z","etag":null,"topics":["canonical-forms","code-comparison","code-transformations","education","equality","equivalence","intension","metaprogramming","type-theory","wolfram-language"],"latest_commit_sha":null,"homepage":"https://paclets.com/Wolfram/CodeEquivalenceUtilities","language":"Mathematica","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/rhennigan.png","metadata":{"files":{"readme":"README.md","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":"2021-10-08T17:17:43.000Z","updated_at":"2025-03-18T05:54:57.000Z","dependencies_parsed_at":"2025-02-02T18:44:12.378Z","dependency_job_id":null,"html_url":"https://github.com/rhennigan/CodeEquivalenceUtilities","commit_stats":null,"previous_names":[],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/rhennigan/CodeEquivalenceUtilities","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhennigan%2FCodeEquivalenceUtilities","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhennigan%2FCodeEquivalenceUtilities/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhennigan%2FCodeEquivalenceUtilities/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhennigan%2FCodeEquivalenceUtilities/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rhennigan","download_url":"https://codeload.github.com/rhennigan/CodeEquivalenceUtilities/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rhennigan%2FCodeEquivalenceUtilities/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28917458,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T16:37:38.804Z","status":"ssl_error","status_checked_at":"2026-01-30T16:37:37.878Z","response_time":66,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["canonical-forms","code-comparison","code-transformations","education","equality","equivalence","intension","metaprogramming","type-theory","wolfram-language"],"created_at":"2024-12-08T08:14:07.105Z","updated_at":"2026-01-30T19:04:41.256Z","avatar_url":"https://github.com/rhennigan.png","language":"Mathematica","readme":"# CodeEquivalenceUtilities\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n[CodeEquivalenceUtilities](https://paclets.com/Wolfram/CodeEquivalenceUtilities) is a collection of Wolfram Language functions that can be used to test if different pieces of code are equivalent without the need for evaluation.\n\nThis allows comparison of unevaluated expressions that may have non-deterministic outputs (e.g. random values, dates, etc).\n\nThis Paclet represents the underlying technology that powers several [automated code grading systems](https://www.wolfram.com/broadcast/video.php?c=104\u0026v=1747\u0026disp=list\u0026ob=date\u0026o=DESC\u0026p=44), such as the [online exercises for EIWL](https://lab.wolframcloud.com/app/view/openEIWL?parentFilePath=elementary-introduction/01-starting-out-elementary-arithmetic-exercises.nb#sidebar=eiwl/01-starting-out-elementary-arithmetic) and [Wolfram Challenges](https://challenges.wolframcloud.com/).\n\u003c/td\u003e\n\u003ctd\u003e\n\u003cimg src=\"Images/hero-image.png\" width=\"80%\"\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n[![View notebooks](https://wolfr.am/HAAhzkRq)](https://wolfr.am/Z72fzrAk) [![Check](https://github.com/rhennigan/CodeEquivalenceUtilities/actions/workflows/Check.yml/badge.svg)](https://github.com/rhennigan/CodeEquivalenceUtilities/actions/workflows/Check.yml) [![Release](https://github.com/rhennigan/CodeEquivalenceUtilities/actions/workflows/Release.yml/badge.svg)](https://github.com/rhennigan/CodeEquivalenceUtilities/actions/workflows/Release.yml)\n\n## Installing CodeEquivalenceUtilities\n\n\n### From the [Wolfram Language Paclet Repository](https://paclets.com)\n\nUsing Wolfram Language version 13.0 or later:\n\n```Mathematica\nPacletInstall[\"Wolfram/CodeEquivalenceUtilities\"]\n```\n\n### Using [GitHubInstall](https://resources.wolframcloud.com/FunctionRepository/resources/GitHubInstall/)\n\nUsing Wolfram Language version 12.0 or later:\n\n```Mathematica\nResourceFunction[\"GitHubInstall\"][\"rhennigan\", \"CodeEquivalenceUtilities\"]\n```\n\n### From Github\nThe CodeEquivalenceUtilities release comes in the form of a `.paclet` file, which contains the entire package and its documentation. Download the latest release from the [GitHub repo's releases page](https://github.com/rhennigan/CodeEquivalenceUtilities/releases). To install, run the following command in the Wolfram Language:\n\n```Mathematica\nPacletInstall[\"/full/path/to/CodeEquivalenceUtilities.paclet\"]\n```\n\nThis will permanently install the CodeEquivalenceUtilities paclet. The Wolfram Language will always use the latest installed version of CodeEquivalenceUtilities. Installed versions can be enumerated using the command:\n\n```Mathematica\nPacletFind[\"Wolfram/CodeEquivalenceUtilities\"]\n```\n\nAnd all versions can be uninstalled using the command:\n\n```Mathematica\nPacletUninstall[\"Wolfram/CodeEquivalenceUtilities\"]\n```\n\n\u003cdetails\u003e\u003csummary\u003e\u003ch2\u003ePaclet Guide\u003c/h2\u003e\u003c/summary\u003e\n\nEquivalence for Wolfram Language code can be defined in many ways. The methods used by CodeEquivalenceUtilities attempt to determine intensional equivalence by transforming expressions into a canonical representation.\n\n### Equivalence Testing\n\n[CodeEquivalentQ](https://paclets.com/Wolfram/CodeEquivalenceUtilities/ref/CodeEquivalentQ.html) - test if two unevaluated expressions are equivalent\n\n[EquivalenceTestData](https://paclets.com/Wolfram/CodeEquivalenceUtilities/ref/EquivalenceTestData.html) - get additional information about the equivalence test performed by \n[CodeEquivalentQ](https://paclets.com/Wolfram/CodeEquivalenceUtilities/ref/CodeEquivalentQ.html)\n\n### Code Transformation\n\n[ToCanonicalForm](https://paclets.com/Wolfram/CodeEquivalenceUtilities/ref/ToCanonicalForm.html) - convert an expression into a canonical representation for direct comparison\n\n[MakeCanonicalForm](https://paclets.com/Wolfram/CodeEquivalenceUtilities/ref/MakeCanonicalForm.html) - convert to canonical form without evaluating the input\n\n[FromCanonicalForm](https://paclets.com/Wolfram/CodeEquivalenceUtilities/ref/FromCanonicalForm.html) - convert a canonical representation back into a normal evaluatable expression\n\n\u003c/details\u003e\n\n## Examples\n\n### Basic Examples\n\nCheck if two expressions are equivalent:\n\n```Mathematica\nCodeEquivalentQ[RandomInteger /@ Range[5], Array[RandomInteger, 5]]\n```\n\u003cimg src=\"Images/674eb267f6beef39.png\" width=\"25\" height=\"17\" style=\"width: 1.5625em; height: 1.0625em; background: white;\"\u003e\n\n---\n\nView the canonical representations of expressions:\n\n```Mathematica\nMakeCanonicalForm[RandomInteger /@ Range[5]]\n```\n\u003cp\u003e\u003cimg src=\"Images/0d12d8551029ee6a.png\" width=\"415\" height=\"27\" style=\"width: 25.9375em; height: 1.6875em; background: white;\"\u003e\u003c/p\u003e\n\n\n```Mathematica\nMakeCanonicalForm[Array[RandomInteger, 5]]\n```\n\u003cimg src=\"Images/59eada987ec4d919.png\" width=\"415\" height=\"27\" style=\"width: 25.9375em; height: 1.6875em; background: white;\"\u003e\n\n\nThese are directly comparable:\n\n```Mathematica\n% === %%\n```\n\u003cimg src=\"Images/5dfbd7b1ec4305fe.png\" width=\"25\" height=\"17\" style=\"width: 1.5625em; height: 1.0625em; background: white;\"\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003ch3\u003eScope\u003c/h3\u003e\u003c/summary\u003e\n\nGet additional information about the equivalence test:\n\n```Mathematica\nEquivalenceTestData[\n    First[Rest[Range /@ Range[2^100]]],\n    Part[Table[Table[j, {j, i}], {i, 2^100}], 2]\n]\n```\n\u003cimg src=\"Images/58724d56ad2d0a5d.png\" width=\"609\" height=\"187\" style=\"width: 38.0625em; height: 11.6875em; background: white;\"\u003e\n\n---\n\nView the sequence of transformations used to convert an expression to its canonical form:\n\n```Mathematica\nMakeCanonicalForm[Array[RandomInteger, 5], \"Trace\" -\u003e True] // Column\n```\n\u003cimg src=\"Images/43a40f076b9b5860.png\" width=\"415\" height=\"171\" style=\"width: 25.9375em; height: 10.6875em; background: white;\"\u003e\n\n\n---\n\nConvert a canonical representation to a normal expression:\n\n```Mathematica\nMakeCanonicalForm[Array[RandomInteger, 5]]\n```\n\u003cimg src=\"Images/3a38f3a85d4a4795.png\" width=\"415\" height=\"27\" style=\"width: 25.9375em; height: 1.6875em; background: white;\"\u003e\n\n\n```Mathematica\nFromCanonicalForm[%]\n```\n\u003cimg src=\"Images/52714167c1555ca8.png\" width=\"389\" height=\"17\" style=\"width: 24.3125em; height: 1.0625em; background: white;\"\u003e\n\nEvaluate:\n\n```Mathematica\nReleaseHold[%]\n```\n\u003cimg src=\"Images/152f8d1bb9acf613.png\" width=\"65\" height=\"17\" style=\"width: 4.0625em; height: 1.0625em; background: white;\"\u003e\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003ch3\u003eNeat Examples\u003c/h3\u003e\u003c/summary\u003e\n\nHere is a list of expressions, some of which are equivalent to others:\n\n```Mathematica\nexpressions = {\n    HoldForm[Table[i, {i, 5}, {j, i + 2}]],\n    HoldForm[Array[Range, 5, 3]],\n    HoldForm[Table[ConstantArray[i, i + 2], {i, 5}]],\n    HoldForm[First[Rest[Range /@ Range[10]]]],\n    HoldForm[Range /@ Range[3, 7]],\n    HoldForm[Part[Table[Table[j, {j, i}], {i, 10}], 2]]\n};\n```\n\nFind the sequence of transformations for each expression:\n\n```Mathematica\nShort[traces = Most@ToCanonicalForm[#, \"Trace\" -\u003e True] \u0026 /@ expressions]\n```\n\u003cimg src=\"Images/0bf8dc73177c188f.png\" width=\"592\" height=\"58\" style=\"width: 37.0000em; height: 3.6250em; background: white;\"\u003e\n\nGenerate a graph for each sequence:\n\n```Mathematica\npaths = Graph[DirectedEdge @@@ Partition[#, 2, 1]] \u0026 /@ traces\n```\n\u003cimg src=\"Images/267c2baf6dadcfcc.png\" width=\"568\" height=\"39\" style=\"width: 35.5000em; height: 2.4375em; background: white;\"\u003e\n\nCombine the graphs:\n\n```Mathematica\ngraph = Graph[GraphUnion @@ paths, Sequence[\n   VertexLabels -\u003e Placed[\"Name\", Tooltip], \n    GraphLayout -\u003e \"LayeredDigraphEmbedding\"]];\n```\n\nEquivalent expressions converge to the same connected component:\n\n```Mathematica\nHighlightGraph[graph, paths]\n```\n\u003cimg src=\"Images/1cd67b7d1f0771ae.png\" width=\"209\" height=\"269\" style=\"width: 13.0625em; height: 16.8125em; background: white;\"\u003e\n\nGroup the expressions into their corresponding equivalence class:\n\n```Mathematica\ngrouped = GroupBy[expressions, ToCanonicalForm]\n```\n\u003cimg src=\"Images/12a4ebc788f8cb2c.png\" width=\"443\" height=\"166\" style=\"width: 27.6875em; height: 10.3750em; background: white;\"\u003e\n\n```Mathematica\nTableForm[KeyValueMap[Reverse@*List, grouped]]\n```\n\u003cimg src=\"Images/751d18c398c2d8f2.png\" width=\"628\" height=\"93\" style=\"width: 39.2500em; height: 5.8125em; background: white;\"\u003e\n\n\u003c/details\u003e\n\n## License\n\nThis project is licensed under the terms of the MIT license. See the LICENSE file in the root directory of this source tree for details.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhennigan%2Fcodeequivalenceutilities","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frhennigan%2Fcodeequivalenceutilities","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frhennigan%2Fcodeequivalenceutilities/lists"}