{"id":21020942,"url":"https://github.com/awto/mfjs-logic","last_synced_at":"2025-05-15T08:31:55.699Z","repository":{"id":143761004,"uuid":"58798451","full_name":"awto/mfjs-logic","owner":"awto","description":"Logical programming in JavaScript","archived":false,"fork":false,"pushed_at":"2016-05-31T18:43:50.000Z","size":7,"stargazers_count":15,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-08T09:35:49.315Z","etag":null,"topics":["constraint-programming","javascript","logic","logic-programming","mfjs","monad"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/awto.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":"2016-05-14T08:48:00.000Z","updated_at":"2023-08-19T10:09:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"30c5a717-143b-4651-b5e7-4a6ba40fe0ec","html_url":"https://github.com/awto/mfjs-logic","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awto%2Fmfjs-logic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awto%2Fmfjs-logic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awto%2Fmfjs-logic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/awto%2Fmfjs-logic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/awto","download_url":"https://codeload.github.com/awto/mfjs-logic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254304639,"owners_count":22048445,"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":["constraint-programming","javascript","logic","logic-programming","mfjs","monad"],"created_at":"2024-11-19T10:44:05.379Z","updated_at":"2025-05-15T08:31:55.681Z","avatar_url":"https://github.com/awto.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Logic programming in JavaScript\n\nThe library is based on\n[Backtracking, Interleaving, and Terminating Monad Transformers](http://okmij.org/ftp/papers/LogicT.pdf)\n\nUsing it with [@mfjs/compiler](https://github.com/awto/mfjs-compiler) turns\nJavaScript into a logical programming language.\n\nFor example, here is almost literal translation of classical Prolog\nbi-directional list append function to JavaScript (defined in separate\n[samples project](https://github.com/awto/mfjs-samples/tree/master/unify)):\n\n```javascript\nfunction append(a,b,r) {\n  const [h, t, rt] = newRefs()\n  unify(a, cons(h, t))\n  unify(r, cons(h, rt))\n  append(t, b, rt)\n  M.answer()\n  unify(a, nil())\n  unify(r, b)\n}\n```\n\nwith usages:\n\n```javascript\nlet l1 = List.from([1,2,3])\nlet l2 = List.from(['a','b','c'])\n// free variables:\nlet [l3,l4,l5] = newRefs()\n\nappend(l1, l2, l3)\nconsole.log('append:', List.toArray(l3))\n// ==\u003e append: [ 1, 2, 3, 'a', 'b', 'c' ]\n\nappend(l1, l4, l3)\nconsole.log('suffix', List.toArray(l4))\n// ==\u003e suffix [ 'a', 'b', 'c' ]\n\nappend(l5, l2, l3)\nconsole.log('prefix', List.toArray(l5))\n// ==\u003e prefix [ 1, 2, 3 ]\n```\n\nor non-determenistic with only result defined:\n\n```javascript\nlet [x,y] = newRefs()\nlet z = List.from([1,2,3,4])\n// only result is instantied \nappend(x,y,z)\nconsole.log('x:', List.toArray(x))\nconsole.log('y:', List.toArray(y))\nconsole.log('z:', List.toArray(z))\n```\n\noutputs all 5 possible answers:\n\n```\nx: [ 1, 2, 3, 4 ]\ny: []\nz: [ 1, 2, 3, 4 ]\n\nx: [ 1, 2, 3 ]\ny: [ 4 ]\nz: [ 1, 2, 3, 4 ]\n\nx: [ 1, 2 ]\ny: [ 3, 4 ]\nz: [ 1, 2, 3, 4 ]\n\nx: [ 1 ]\ny: [ 2, 3, 4 ]\nz: [ 1, 2, 3, 4 ]\n\nx: []\ny: [ 1, 2, 3, 4 ]\nz: [ 1, 2, 3, 4 ]\n```\n\n## API\n\nIn standard Prolog language there is only depth first search options for\npossible answer lookup. The library provides means to add arbitrary search\nstrategies. By default it provides depth-first and breadth-first searches.\n\nResult object returned from `L.run` is ES iterable. Its default iterator\ntraverses answers in depth-first order. The result object also has `bfs`\nfunction returning iterator for breadth first order.\n\nThere are a few additional functions in logic monad definition:\n\n * once - takes logical computation and returns only its first answer if any\n * level - for logical computation returns object with either field `value`\n   or `alts`, the first is final result of the computation and the second\n   is a list of other logical computations if original one was non-deterministic\n\n## Usage\n\n```\n$ npm install --save-dev @mfjs/compiler\n$ npm install --save @mfjs/core @mfjs/logic\n$ mfjsc input.js --output=out\n# or for browser\n$ browserify -t @mfjsc/compiler/monadify input.js -o index.js\n```\n\n## \n\n## License\n\nCopyright © 2016 Vitaliy Akimov\n\nDistributed under the terms of the [The MIT License (MIT)](LICENSE). \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawto%2Fmfjs-logic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fawto%2Fmfjs-logic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fawto%2Fmfjs-logic/lists"}