{"id":26207442,"url":"https://github.com/oelin/fol","last_synced_at":"2026-05-15T16:35:16.624Z","repository":{"id":89778702,"uuid":"482117869","full_name":"oelin/fol","owner":"oelin","description":"A semantically accurate implementation of first-order logic in JavaScript 👩‍🏫.","archived":false,"fork":false,"pushed_at":"2023-01-21T12:54:59.000Z","size":45,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-27T01:59:09.196Z","etag":null,"topics":["computer-science","first-order-logic","javascript","logic","predicate-logic"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oelin.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2022-04-16T00:29:06.000Z","updated_at":"2023-12-05T18:02:45.000Z","dependencies_parsed_at":"2023-03-13T18:05:06.005Z","dependency_job_id":null,"html_url":"https://github.com/oelin/fol","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/oelin/fol","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Ffol","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Ffol/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Ffol/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Ffol/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oelin","download_url":"https://codeload.github.com/oelin/fol/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oelin%2Ffol/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33072612,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-15T11:35:32.926Z","status":"ssl_error","status_checked_at":"2026-05-15T11:35:31.362Z","response_time":103,"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":["computer-science","first-order-logic","javascript","logic","predicate-logic"],"created_at":"2025-03-12T05:32:33.667Z","updated_at":"2026-05-15T16:35:16.618Z","avatar_url":"https://github.com/oelin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FOL\n\nThis library provides a semantically accurate implementation of [first-order logic (FOL)](https://en.wikipedia.org/wiki/First-order_logic) in JavaScript. It aims to closely replicate the standard set-theoretic formulation of FOL.\n\n\n## Concepts \n\nThis library aims to implement all *primary* concepts found within the standard definition of FOL.\n\n| Concept                                                                                          | Implementation                                                                                                                    |\n|--------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|\n| [First Order Language](https://en.wikipedia.org/wiki/First-order_logic#Syntax)                   | `FirstOrderLanguage(constantSymbols, variableSymbols, functionSymbols, predicateSymbols)`, `FirstOrderParser(firstOrderLanguage)` |\n| [First Order Structure](https://en.wikipedia.org/wiki/First-order_logic#Semantics)               | `FirstOrderStructure(firstOrderLanguage, domain, constantsMap, functionsMap, predicatesMap)`                                      |\n| [Interpretation Function](https://en.wikipedia.org/wiki/Interpretation_(logic))                   | `FirstOrderStructure.interpret(symbol)`                                                                                           |\n| [Domain Of Discourse](https://en.wikipedia.org/wiki/Domain_of_discourse)                         | `FirstOrderStructure.domain`                                                                                                      |\n| [Variable Binding](https://en.wikipedia.org/wiki/First-order_logic#Free_and_bound_variables)     | `FirstOrderAssignment(?variableMap)`                                                                                              |\n| [Formula Evaluation](https://en.wikipedia.org/wiki/First-order_logic#Free_and_bound_variables)   | `FirstOrderEvaluator(firstOrderStructure, ?firstOrderAssignment)`                                                                 |\n\n## Usage\n\n### Creating First-Order Models\n\nIn this example we create a first-order model for modulo-10 arithmetic.\n\n```js\n// The domain of discourse.\n\nconst domain = new Set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])\n\n\n// Variables.\n\nconst variables = ['x', 'y', 'z', 'a', 'b', 'c']\n\n\n// Mapping between constant symbols and their interpretations.\n\nconst constantsMap = {\n  0: 0,\n  1: 1,\n  2: 2,\n  3: 3,\n  4: 4,\n  5: 5,\n  6: 6,\n  7: 7,\n  8: 8,\n  9: 9\n}\n\n\n// Mapping between function symbols and their interpretations.\n\nfunction mod10(n) {\n    return ((n % 10) + 10) % 10\n}\n\n\nconst functionsMap = {\n\n  // Addition.\n  \n  F(x, y) {\n    return mod10(x + y)\n  },\n  \n  // Subtraction.\n  \n  G(x, y) {\n    return mod10(x - y)\n  },\n  \n  // Successor relation.\n  \n  S(x) {\n    return mod10(x + 1)\n  },\n  \n  // Predecessor\n  \n  P(x) {\n    return mod10(x - 1)\n  },\n  \n  // Additive inverse.\n  \n  I(x) {\n    return mod10(-x)\n  }\n}\n\n\n// Mapping between predicates and their interpretations.\n\nconst predicatesMap = {\n\n  // Equality in the domain.\n  \n  M(x, y) {\n    return x === y\n  },\n  \n  // Less-than relation.\n  \n  L(x, y) {\n    return x \u003c y\n  }\n}\n\n\n// Create the first-order model.\n\nconst model = new FirstOrderLogic(\n  domain,\n  variables,\n  constantsMap,\n  functionsMap,\n  predicatesMap\n)\n```\n\n### Evaluating Formulae\n\nFor all `x`, there is a `y` such that `y` is the successor of `x`. This should be true.\n\n```js\nmodel.evaluate('AxEyM(y,S(x))') // true\n```\n\nThere is no smallest `x`. This should be false.\n\n```js\nmodel.evaluate('-ExAy(-M(x,y)\u003eL(x,y))') // false\n```\n\nThe successor of the predecessor of `x` is equal to `x`. This should be true.\n\n```js\nmodel.evaluate('AxM(S(P(x)),x)') // true\n```\n\nThe successor of the largest element of the domain is the smallest element of the domain. This should be true.\n\n```js\nmodel.evaluate('ExEy((Az(-M(x,y)\u003eL(x,z))^Az(-M(y,z)\u003eL(z,y)))\u003eM(S(y),x))') // true\n```\n\nThere is an element which when summed with its additive inverse, results in 1. This should be false.\n\n```js\nmodel.evaluate('ExM(1,F(x,I(x)))') // false\n```\n\nAny element summed with its additive inverse results in 0. This should be true.\n\n```js\nmodel.evaluate('AxM(0,F(x,I(x)))') // true\n```\n\nThere is an element which is its own additive inverse. This should be true, namely on `x=0` and `x=5`.\n\n```js\nmodel.evaluate('ExM(x,I(x))') // true\n```\n\n## Efficiency\n\nIn this implementation, quantifiers are evaluated by iterating over the domain. Hence, nesting quantifiers leads to nested iteration and therefore a significant \nincrease in evaluation time. If you have three layers of quantification for example, the evaluation time is at worst cubic in the size of the domain.\n\n\n## Future\n\n* Add support for multicharacter predicate names.\n* Add equality as a primitive binary connective.\n* There's currently working implementations of propositional and modal logic in `future.js`, however they need to be refactored.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foelin%2Ffol","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foelin%2Ffol","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foelin%2Ffol/lists"}