{"id":23950095,"url":"https://github.com/pythological/kanren","last_synced_at":"2026-02-18T20:32:04.184Z","repository":{"id":41081551,"uuid":"176787814","full_name":"pythological/kanren","owner":"pythological","description":"An extensible, lightweight relational/logic programming DSL written in pure Python","archived":false,"fork":false,"pushed_at":"2025-08-22T23:04:24.000Z","size":564,"stargazers_count":227,"open_issues_count":24,"forks_count":24,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-10-20T16:22:34.632Z","etag":null,"topics":["clp","constraint-logic-programming","logic-programming","minikanren","relational-programming","symbolic-computation"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pythological.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["brandonwillard"]}},"created_at":"2019-03-20T17:50:10.000Z","updated_at":"2025-10-18T19:20:18.000Z","dependencies_parsed_at":"2025-08-22T22:34:08.800Z","dependency_job_id":null,"html_url":"https://github.com/pythological/kanren","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/pythological/kanren","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pythological%2Fkanren","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pythological%2Fkanren/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pythological%2Fkanren/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pythological%2Fkanren/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pythological","download_url":"https://codeload.github.com/pythological/kanren/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pythological%2Fkanren/sbom","scorecard":{"id":752110,"data":{"date":"2025-08-11","repo":{"name":"github.com/pythological/kanren","commit":"48cc456d19e15754df697713365c20c45ec45e91"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":5.2,"checks":[{"name":"Maintained","score":7,"reason":"7 commit(s) and 2 issue activity found in the last 90 days -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yml:27: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pypi.yml:57: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/pypi.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/pypi.yml:61: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/pypi.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/tests.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/tests.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:50: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:51: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/tests.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/tests.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:71: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/tests.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/tests.yml:72: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/tests.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/tests.yml:83: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/tests.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/tests.yml:105: update your workflow using https://app.stepsecurity.io/secureworkflow/pythological/kanren/tests.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/pypi.yml:32","Warn: pipCommand not pinned by hash: .github/workflows/pypi.yml:39","Warn: pipCommand not pinned by hash: .github/workflows/tests.yml:77","Warn: pipCommand not pinned by hash: .github/workflows/tests.yml:78","Info:   0 out of   9 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   5 third-party GitHubAction dependencies pinned","Info:   1 out of   5 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Code-Review","score":4,"reason":"Found 9/20 approved changesets -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/pypi.yml:1","Warn: no topLevel permission defined: .github/workflows/tests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/pypi.yml:51"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T20:39:28.415Z","repository_id":41081551,"created_at":"2025-08-22T20:39:28.415Z","updated_at":"2025-08-22T20:39:28.415Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29594259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-18T18:54:29.675Z","status":"ssl_error","status_checked_at":"2026-02-18T18:50:50.517Z","response_time":162,"last_error":"SSL_read: 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":["clp","constraint-logic-programming","logic-programming","minikanren","relational-programming","symbolic-computation"],"created_at":"2025-01-06T12:00:40.629Z","updated_at":"2026-02-18T20:32:04.160Z","avatar_url":"https://github.com/pythological.png","language":"Python","funding_links":["https://github.com/sponsors/brandonwillard"],"categories":["Python"],"sub_categories":[],"readme":"# `kanren`\n\n[![Build Status](https://travis-ci.org/pythological/kanren.svg?branch=main)](https://travis-ci.org/pythological/kanren) [![Coverage Status](https://coveralls.io/repos/github/pythological/kanren/badge.svg?branch=main)](https://coveralls.io/github/pythological/kanren?branch=main) [![PyPI](https://img.shields.io/pypi/v/miniKanren)](https://pypi.org/project/miniKanren/) [![Join the chat at https://gitter.im/pythological/kanren](https://badges.gitter.im/pythological/kanren.svg)](https://gitter.im/pythological/kanren?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\nLogic/relational programming in Python with [miniKanren](http://minikanren.org/).\n\n## Installation\n\nUsing `pip`:\n```bash\npip install miniKanren\n```\n\nUsing `conda`:\n```bash\nconda install -c conda-forge miniKanren\n```\n\n## Development\n\nFirst obtain the project source:\n```bash\ngit clone git@github.com:pythological/kanren.git\ncd kanren\n```\n\nInstall the development dependencies:\n\n```bash\n$ pip install -r requirements.txt\n```\n\nSet up `pre-commit` hooks:\n\n```bash\n$ pre-commit install --install-hooks\n```\n\nTests can be run with the provided `Makefile`:\n```bash\nmake check\n```\n\n## Motivation\n\nLogic programming is a general programming paradigm.  This implementation however came about specifically to serve as an algorithmic core for Computer Algebra Systems in Python and for the automated generation and optimization of numeric software.  Domain specific languages, code generation, and compilers have recently been a hot topic in the Scientific Python community.  `kanren` aims to be a low-level core for these projects.\n\nThese points\u0026mdash;along with `kanren` examples\u0026mdash;are covered in the paper [\"miniKanren as a Tool for Symbolic Computation in Python\"](https://arxiv.org/abs/2005.11644).\n\n## Examples\n\n`kanren` enables one to express sophisticated relations\u0026mdash;in the form of *goals*\u0026mdash;and generate values that satisfy the relations.  The following code is the \"Hello, world!\" of logic programming; it asks for values of the *logic variable* `x` such that `x == 5`:\n\n```python\n\u003e\u003e\u003e from kanren import run, eq, membero, var, lall\n\u003e\u003e\u003e x = var()\n\u003e\u003e\u003e run(1, x, eq(x, 5))\n(5,)\n```\n\nMultiple logic variables and goals can be used simultaneously.  The following code asks for one list containing the values of `x` and `z` such that `x == z` **and** `z == 3`:\n\n```python\n\u003e\u003e\u003e z = var()\n\u003e\u003e\u003e run(1, [x, z], eq(x, z),\n                   eq(z, 3))\n([3, 3],)\n```\n\n`kanren` uses [unification](http://en.wikipedia.org/wiki/Unification_%28computer_science%29) to match forms within expression trees.  The following code asks for values of `x` such that `(1, 2) == (1, x)`:\n\n```python\n\u003e\u003e\u003e run(1, x, eq((1, 2), (1, x)))\n(2,)\n```\n\nThe above examples use `eq`: a *goal constructor* that creates a goal for unification between two objects.  Other goal constructors, such as `membero(item, coll)`, express more sophisticated relations and are often constructed from simpler ones like `eq`.  More specifically, `membero` states that `item` is a member of the collection `coll`.\n\nThe following example uses `membero` to ask for *all* values of `x`, such that `x` is a member of `(1, 2, 3)` **and** `x` is a member of `(2, 3, 4)`.\n\n```python\n\u003e\u003e\u003e run(0, x, membero(x, (1, 2, 3)),  # x is a member of (1, 2, 3)\n              membero(x, (2, 3, 4)))  # x is a member of (2, 3, 4)\n(2, 3)\n```\n\nThe examples above made implicit use of the goal constructors `lall` and `lany`, which represent goal *conjunction* and *disjunction*, respectively.  Many useful relations can be expressed with `lall`, `lany`, and `eq` alone, but in `kanren` it's also easy to leverage the host language and explicitly create any relation expressible in Python.\n\n### Representing Knowledge\n\n`kanren` stores data as facts that state relationships between terms.  The following code creates a parent relationship and uses it to state facts about who is a parent of whom within the Simpsons family:\n\n```python\n\u003e\u003e\u003e from kanren import Relation, facts\n\u003e\u003e\u003e parent = Relation()\n\u003e\u003e\u003e facts(parent, (\"Homer\", \"Bart\"),\n...               (\"Homer\", \"Lisa\"),\n...               (\"Abe\",  \"Homer\"))\n\n\u003e\u003e\u003e run(1, x, parent(x, \"Bart\"))\n('Homer',)\n\n\u003e\u003e\u003e run(2, x, parent(\"Homer\", x))\n('Lisa', 'Bart')\n```\n\nWe can use intermediate variables for more complex queries.  For instance, who is Bart's grandfather?\n\n```python\n\u003e\u003e\u003e grandparent_lv, parent_lv = var(), var()\n\u003e\u003e\u003e run(1, grandparent_lv, parent(grandparent_lv, parent_lv),\n                           parent(parent_lv, 'Bart'))\n('Abe',)\n```\n\nWe can express the grandfather relationship as a distinct relation by creating a goal constructor:\n```python\n\u003e\u003e\u003e def grandparent(x, z):\n...     y = var()\n...     return lall(parent(x, y), parent(y, z))\n\n\u003e\u003e\u003e run(1, x, grandparent(x, 'Bart'))\n('Abe,')\n```\n\n## Constraints\n\n`kanren` provides a fully functional constraint system that allows one to restrict unification and object types:\n\n```python\n\u003e\u003e\u003e from kanren.constraints import neq, isinstanceo\n\n\u003e\u003e\u003e run(0, x,\n...     neq(x, 1),  # Not \"equal\" to 1\n...     neq(x, 3),  # Not \"equal\" to 3\n...     membero(x, (1, 2, 3)))\n(2,)\n\n\u003e\u003e\u003e from numbers import Integral\n\u003e\u003e\u003e run(0, x,\n...     isinstanceo(x, Integral),  # `x` must be of type `Integral`\n...     membero(x, (1.1, 2, 3.2, 4)))\n(2, 4)\n```\n\n## Graph Relations\n\n`kanren` comes with support for relational graph operations suitable for basic symbolic algebra operations.  See the examples in [`doc/graphs.md`](doc/graphs.md).\n\n## Extending `kanren`\n\n`kanren` uses the [`logical-unification` library](https://github.com/pythological/unification) to support pattern matching on user defined types.  Essentially, types that can be unified can be used with most `kanren` goals.  See the [`logical-unification` project's examples](https://github.com/pythological/unification#examples) for demonstrations of how arbitrary types can be made unifiable.\n\n## About\n\nThis project is a fork of [`logpy`](https://github.com/logpy/logpy).\n\n## References\n\n* [Logic Programming on wikipedia](http://en.wikipedia.org/wiki/Logic_programming)\n* [miniKanren](http://minikanren.org/), a Scheme library for relational programming on which this library is based.  More information can be found in the\n[thesis of William\nByrd](https://scholarworks.iu.edu/dspace/bitstream/handle/2022/8777/Byrd_indiana_0093A_10344.pdf).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpythological%2Fkanren","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpythological%2Fkanren","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpythological%2Fkanren/lists"}