{"id":17061071,"url":"https://github.com/chalcolith/pony-kanren","last_synced_at":"2026-01-05T06:14:38.041Z","repository":{"id":70779017,"uuid":"131766718","full_name":"chalcolith/pony-kanren","owner":"chalcolith","description":"An implementation of microKanren for Pony.","archived":false,"fork":false,"pushed_at":"2018-05-04T21:57:10.000Z","size":24,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-28T14:48:11.363Z","etag":null,"topics":["kanren","logic-programming","pony-language","ponylang"],"latest_commit_sha":null,"homepage":null,"language":"Pony","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chalcolith.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2018-05-01T21:48:45.000Z","updated_at":"2019-12-01T13:58:38.000Z","dependencies_parsed_at":"2023-07-14T08:31:54.482Z","dependency_job_id":null,"html_url":"https://github.com/chalcolith/pony-kanren","commit_stats":null,"previous_names":["chalcolith/pony-kanren","kulibali/pony-kanren"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chalcolith%2Fpony-kanren","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chalcolith%2Fpony-kanren/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chalcolith%2Fpony-kanren/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chalcolith%2Fpony-kanren/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chalcolith","download_url":"https://codeload.github.com/chalcolith/pony-kanren/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245072266,"owners_count":20556353,"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":["kanren","logic-programming","pony-language","ponylang"],"created_at":"2024-10-14T10:46:00.401Z","updated_at":"2026-01-05T06:14:38.002Z","avatar_url":"https://github.com/chalcolith.png","language":"Pony","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pony-Kanren\n\nPony-Kanren is an implementation of [microKanren](http://minikanren.org/) for\nthe [Pony programming language](https://www.ponylang.org).\n\nThe easiest way to use Pony-Kanren in your code is via\n[Pony-Stable](https://github.com/ponylang/pony-stable): run\n\n```bash\nstable add github kulibali/pony-kanren\n```\nto add Pony-Kanren as a dependency to your `bundle.json`, and then\n```pony\nuse \"kanren\"\n```\n\nin your code to import the library.\n\nYou can find library documentation\n[here](http://kulibali.github.io/pony-kanren/kanren--index/).\n\n## Workflow\n\nTo set up a logic expression and query its results:\n\n- Create an empty `State` value, with a functor that can unify the data type\n  that your variables refer to.\n- Create a `Goal` that represents a logical expression.\n  - Use the `Goal.fresh()` function to obtain a new state that knows about a\n    variable.  That variable will now be visible to subgoals.  Note that if you\n    use `Goal.fresh()` more than once, the variables will be disjoint.  If their\n    scopes intersect, you will get errors.\n  - Use `Goal.conj()` for the logical AND operation.  This will succeed only if\n    both its subgoals succeed.\n  - `Goal.disj()` is logical OR.  This will succeed if either of its subgoals\n    succeeds.\n  - `Goal.unify_vars()` will unify two variables, if possible.\n  - `Goal.unify_vals()` will attempt to structurally unify two values.\n  - `Goal.unify_val()` will bind a variable to a value, if possible.\n- A goal is a function that returns a sequence of states.  Each state may contain\n  variable bindings that represent a solution to the logical expression.\n  - If there is no solution for the expression, the sequence will be empty.\n  - If an error occurrs when solving, the sequence will contain a solution with\n    unbound variables and some error messages obtainable via its `get_errors()`\n    method.\n- You can query the value of any variable in a particular state using the\n  state's `apply()` method.\n\n## Example\n\nThe following Pony code initializes and solves the expression\n`A = B \u0026\u0026 (B = 123 || B = 456)`.  Running the goal will result in a sequence of\ntwo states, one where `A` and `B` are bound to `123`, and one where `A` and `B`\nare bound to `456`:\n\n```pony\nuse \"kanren\"\n\nlet a = Var(\"A\")\nlet b = Var(\"B\")\nlet g =\n  Goals.fresh[USize](a,\n    Goals.fresh[USize](b,\n      Goals.conj[USize](\n        Goals.unify_vars[USize](b, a),\n        Goals.disj[USize](\n          Goals.unify_val[USize](b, 123),\n          Goals.unify_val[USize](b, 456)\n        ))))\n\nlet results = g(State[USize](UnifyEq[USize]))\nlet s1 = results.next()?\ns1(a) == 123 // true\ns1(b) == 123 // true\nlet s2 = results.next()?\ns2(a) == 456 // true\ns2(b) == 456 // true\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchalcolith%2Fpony-kanren","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchalcolith%2Fpony-kanren","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchalcolith%2Fpony-kanren/lists"}