{"id":16685468,"url":"https://github.com/dpalmasan/py-logic","last_synced_at":"2025-03-17T00:32:55.182Z","repository":{"id":44412748,"uuid":"512513574","full_name":"dpalmasan/py-logic","owner":"dpalmasan","description":"Libray for dealing with logic in python","archived":false,"fork":false,"pushed_at":"2024-07-01T14:56:53.000Z","size":114,"stargazers_count":5,"open_issues_count":10,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-16T06:41:14.827Z","etag":null,"topics":["aima","artificial-intelligence","artificial-intelligence-algorithms","logic","logic-programming","python"],"latest_commit_sha":null,"homepage":"","language":"Python","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/dpalmasan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"code_of_conduct.md","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-07-10T18:47:56.000Z","updated_at":"2025-03-04T14:24:16.000Z","dependencies_parsed_at":"2024-10-27T11:49:15.490Z","dependency_job_id":"fb009957-5e91-4fd4-8016-39be5ea12f4a","html_url":"https://github.com/dpalmasan/py-logic","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpalmasan%2Fpy-logic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpalmasan%2Fpy-logic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpalmasan%2Fpy-logic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dpalmasan%2Fpy-logic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dpalmasan","download_url":"https://codeload.github.com/dpalmasan/py-logic/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243955668,"owners_count":20374371,"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":["aima","artificial-intelligence","artificial-intelligence-algorithms","logic","logic-programming","python"],"created_at":"2024-10-12T14:47:21.830Z","updated_at":"2025-03-17T00:32:54.895Z","avatar_url":"https://github.com/dpalmasan.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Pylogic: A logic programming library for python\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/dpalmasan/py-logic/actions\"\u003e\u003cimg alt=\"Actions Status\" src=\"https://github.com/dpalmasan/py-logic/workflows/build/badge.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/dpalmasan/py-logic\" \u003e \u003cimg src=\"https://codecov.io/gh/dpalmasan/py-logic/branch/main/graph/badge.svg?token=1ROCTA6VNM\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/dpalmasan/py-logic/blob/master/LICENSE\"\u003e\u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/github/license/dpalmasan/py-logic\"\u003e\u003c/a\u003e\n\u003ca href=\"https://www.contributor-covenant.org/\" \u003e \u003cimg src=\"https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg\"/\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/psf/black\"\u003e\u003cimg alt=\"Code style: black\" src=\"https://img.shields.io/badge/code%20style-black-000000.svg\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Overview\n\n`Pylogic` is a library to integrate logic programming to your python programs. Currently it supports propositional logic, and a subset of first order logic (Horn Clauses). The API is supposed to be expressive as `python` is as a language.\n\n## Install\n\n```\npip install python-logic\n```\n\n### Examples\n\n```python\na = Literal(\"P\", True)\nb = Literal(\"Q\", True)\n\nprint(a | b)\nprint(~a | b)\nprint(~(a | b ))\n```\n\nOutput:\n\n```\nP v Q\n¬P v Q\n¬P ^ ¬Q\n```\n\n#### Making inferences using the resolution rule (Propositional Logic)\n\nSuppose we have the following knowledge base (KB):\n\n$$(B_{11} \\Leftrightarrow (P_{12} \\vee P_{21})) \\wedge \\neg B_{11}$$\n\nAnd we want to prove $\\alpha = \\neg P_{12}$.\n\nWe could use several algorithms, based on desired KB type as shown in the code below.\n\n```python\nfrom pylogic.propositional import (\n    BicondClause,\n    DpllKB,\n    ResolutionKB,\n    Variable,\n)\n\nB11 = Variable(\"B11\", True)\nP12 = Variable(\"P12\", True)\nP21 = Variable(\"P21\", True)\nclauses = BicondClause(B11, (P12 | P21)) \u0026 ~B11\nkb = ResolutionKB(clauses)\nalpha = Variable(\"P12\", False)\nprint(f\"Ask entailment of {alpha} using resolution:\", kb.query(alpha))\nkb = DpllKB(clauses)\nprint(f\"Ask entailment of {alpha} using DPLL algorithm:\", kb.query(alpha))\n\nkb = ResolutionKB(clauses)\nalpha = B11 \u0026 ~B11\nprint(f\"Ask entailment of {alpha} using resolution:\", kb.query(alpha))\nkb = DpllKB(clauses)\nprint(f\"Ask entailment of {alpha} using DPLL algorithm:\", kb.query(alpha))\n```\n\nOutput:\n\n```\nAsk entailment of P12 using resolution: True\nAsk entailment of P12 using DPLL algorithm: True\nAsk entailment of ¬B11 ^ B11 using resolution: False\nAsk entailment of ¬B11 ^ B11 using DPLL algorithm: False\n```\n\n#### Using First Order Logic (Forward and Backward chaining)\n\nExamples are located under `/examples` folder. Lets go with the example in the AIMA (Artificial Intelligence a Modern Approach) example, we have the following predicates:\n\n1. It is a crime for an american to sell weapons to hostile nations\n\n\n```math\n\\begin{array} {   rr} \\quad American(x) \\land Weapon(y) \\land \\\\ Sells(x, y, z) \\land Hostile(z) \\Rightarrow Criminal(x) \\end{array}\n\n$$ $$\n```\n\n2. Nono has some missiles:\n\n$$Owns(Nono, M1)$$\n\n$$Missile(M1)$$\n\n3. All missiles were sold to it by Colonel West\n\n$$Missile(x) \\land Owns(Nono, x) \\Rightarrow Sells(West, x, Nono)$$\n\n4. Missiles are weapons\n\n$$Missile(x) \\Rightarrow Weapon(x)$$\n\n5. An enemy of America counts as Hostile:\n\n$$Enemy(x, America) \\Rightarrow Hostile(x)$$\n\n6. West who is american\n\n$$American(West)$$\n\n7. The country of Nono an enemy of America\n\n$$Enemy(Nono, America)$$\n\n8. Prove west is a Criminal\n\n$$Criminal(West)$$\n\nLet us use forward chaining, the code would look as follows:\n\n```python\nfrom pylogic.fol import (\n    HornClauseFOL,\n    Predicate,\n    Term,\n    TermType,\n    fol_bc_ask,\n    Substitution,\n    fol_fc_ask,\n)\n\n\nx = Term(\"x\", TermType.VARIABLE)\ny = Term(\"y\", TermType.VARIABLE)\nz = Term(\"z\", TermType.VARIABLE)\n\nnono = Term(\"Nono\", TermType.CONSTANT)\nwest = Term(\"West\", TermType.CONSTANT)\nm1 = Term(\"M1\", TermType.CONSTANT)\namerica = Term(\"America\", TermType.CONSTANT)\n\np1 = Predicate(\"American\", [x])\np2 = Predicate(\"Weapon\", [y])\np3 = Predicate(\"Sells\", [x, y, z])\np4 = Predicate(\"Hostile\", [z])\np5 = Predicate(\"Criminal\", [x])\np6 = Predicate(\"Owns\", [nono, m1])\np7 = Predicate(\"Missile\", [m1])\np8 = Predicate(\"Missile\", [x])\np9 = Predicate(\"Owns\", [nono, x])\np10 = Predicate(\"Sells\", [west, x, nono])\np11 = Predicate(\"Weapon\", [x])\np12 = Predicate(\"Enemy\", [x, america])\np13 = Predicate(\"American\", [west])\np14 = Predicate(\"Enemy\", [nono, america])\n\nhc1 = HornClauseFOL([p1, p2, p3, p4], p5)\nhc2 = HornClauseFOL([], p6)\nhc3 = HornClauseFOL([], p7)\nhc4 = HornClauseFOL([p8, p9], p10)\nhc5 = HornClauseFOL([p8], p11)\nhc6 = HornClauseFOL([p12], Predicate(\"Hostile\", [x]))\nhc7 = HornClauseFOL([], p13)\nhc8 = HornClauseFOL([], p14)\n\nkb = [\n    hc1,\n    hc2,\n    hc3,\n    hc4,\n    hc5,\n    hc6,\n    hc7,\n    hc8,\n]\n\ngoal = Predicate(\"Criminal\", [west])\nfor rule in kb:\n    print(rule)\n\nprint(\"Forward Chaining:\")\n\nsub = fol_fc_ask(kb, Predicate(\"Criminal\", [west]))\nfor k, v in sub.substitution_values.items():\n    print(k, v)\n\nprint(\"Backward Chaining:\")\nanswers = fol_bc_ask(kb, [goal], Substitution({}))\nfor answer in answers:\n    for k, v in answer.substitution_values.items():\n        print(k, v)\n```\n\nOutput (Notice that variables will be standardized, to avoid unification issues)\n\n```\nAmerican(x) ^ Hostile(z) ^ Sells(x, y, z) ^ Weapon(y) =\u003e Criminal(x)\nOwns(Nono, M1)\nMissile(M1)\nMissile(x) ^ Owns(Nono, x) =\u003e Sells(West, x, Nono)\nMissile(x) =\u003e Weapon(x)\nEnemy(x, America) =\u003e Hostile(x)\nAmerican(West)\nEnemy(Nono, America)\nForward Chaining:\nx0 West\nz1 Nono\ny2 M1\nBackward Chaining:\nx4 M1\ny2 M1\nx3 y2\nz1 Nono\nx5 z1\nx0 West\n```\n\nLet's take a more challenging problem, the coloreable map:\n\n```math\n\\begin{array} {   rr} \\quad Diff(wa, nt) \\land Diff(wa, sa) \\land \\\\ Diff(nt, q) \\land Diff(nt, sa) \\land \\\\ Diff(q, nsw) \\land Diff(q, sa) \\land \\\\ Diff(nsw, v) \\land Diff(nsw, a) \\land \\\\ Diff(v, sa) \\Rightarrow Coloreable() \\\\ Diff(Red, Blue) \\quad Diff(Red, Green) \\\\ Diff(Blue, Red) \\quad Diff(Blue, Green) \\\\ Diff(Green, Red) \\quad Diff(Green, Blue) \\end{array}\n```\n\nCurrently, forward chaining will get stuck due to being a hard-matching problem, and that the current FC implementation is naive:\n\n```python\nfrom pylogic.fol import (\n    HornClauseFOL,\n    Predicate,\n    Term,\n    TermType,\n    fol_bc_ask,\n    Substitution,\n)\n\nwa = Term(\"wa\", TermType.VARIABLE)\nsa = Term(\"sa\", TermType.VARIABLE)\nnt = Term(\"nt\", TermType.VARIABLE)\nq = Term(\"q\", TermType.VARIABLE)\nnsw = Term(\"nsw\", TermType.VARIABLE)\nv = Term(\"v\", TermType.VARIABLE)\nt = Term(\"t\", TermType.VARIABLE)\n\nmap = HornClauseFOL(\n    [\n        Predicate(\"Diff\", [wa, nt]),\n        Predicate(\"Diff\", [wa, sa]),\n        Predicate(\"Diff\", [nt, q]),\n        Predicate(\"Diff\", [nt, sa]),\n        Predicate(\"Diff\", [q, nsw]),\n        Predicate(\"Diff\", [q, sa]),\n        Predicate(\"Diff\", [nsw, v]),\n        Predicate(\"Diff\", [nsw, sa]),\n        Predicate(\"Diff\", [v, sa]),\n    ],\n    Predicate(\"Colorable\", []),\n)\n\nred = Term(\"Red\", TermType.CONSTANT)\nblue = Term(\"Blue\", TermType.CONSTANT)\ngreen = Term(\"Green\", TermType.CONSTANT)\n\np1 = HornClauseFOL(\n    [],\n    Predicate(\"Diff\", [red, blue]),\n)\np2 = HornClauseFOL(\n    [],\n    Predicate(\"Diff\", [red, green]),\n)\np3 = HornClauseFOL(\n    [],\n    Predicate(\"Diff\", [green, red]),\n)\np4 = HornClauseFOL(\n    [],\n    Predicate(\"Diff\", [green, blue]),\n)\np5 = HornClauseFOL(\n    [],\n    Predicate(\"Diff\", [blue, red]),\n)\np6 = HornClauseFOL([], Predicate(\"Diff\", [blue, green]))\n\nkb = [map, p1, p2, p3, p4, p5, p6]\n\ngoal = Predicate(\"Colorable\", [])\nanswers = fol_bc_ask(kb, [goal], Substitution({}))\n\nfor answer in answers:\n    for k, v in answer.substitution_values.items():\n        print(k, v)\n    print(\"=\" * 7)\n```\n\nOutput (All possible variable assignments):\n\n```\nv5 Blue\nnsw4 Green\nq3 Blue\nsa2 Red\nwa0 Blue\nnt1 Green\n=======\nv5 Blue\nnsw4 Red\nq3 Blue\nsa2 Green\nwa0 Blue\nnt1 Red\n=======\nv5 Green\nnsw4 Blue\nq3 Green\nsa2 Red\nwa0 Green\nnt1 Blue\n=======\nv5 Green\nnsw4 Red\nq3 Green\nsa2 Blue\nwa0 Green\nnt1 Red\n=======\nv5 Red\nnsw4 Green\nq3 Red\nsa2 Blue\nwa0 Red\nnt1 Green\n=======\nv5 Red\nnsw4 Blue\nq3 Red\nsa2 Green\nwa0 Red\nnt1 Blue\n=======\n```\n\n\n## Goals\n\nThis library could be used to create logic agents, or even inference engines to be easily integrated with `python`. There is multiple work to be done, but a current goal is to be able to apply an intersection between `Machine Learning` and `Logic Programming` that is built solely on python, and with the flexibility of using different algorithms depending the context.\n\n## Code of Conduct\n\nEveryone participating in the _Pylogic_ project, and in particular in the issue tracker,\npull requests, and social media activity, is expected to treat other people with respect\nand more generally to follow the guidelines articulated in the\n[Covenant Code of Conduct](code_of_conduct.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpalmasan%2Fpy-logic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdpalmasan%2Fpy-logic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdpalmasan%2Fpy-logic/lists"}