{"id":13749305,"url":"https://github.com/Janko-dev/plogic","last_synced_at":"2025-05-09T12:32:30.468Z","repository":{"id":136267441,"uuid":"533624137","full_name":"Janko-dev/plogic","owner":"Janko-dev","description":"Propositional logic evaluator and rule-based pattern matcher","archived":false,"fork":false,"pushed_at":"2022-09-14T12:47:58.000Z","size":29,"stargazers_count":20,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-05-22T22:32:53.481Z","etag":null,"topics":["logic","repl","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","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/Janko-dev.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}},"created_at":"2022-09-07T05:47:33.000Z","updated_at":"2024-02-18T18:29:40.000Z","dependencies_parsed_at":null,"dependency_job_id":"9e2b4ab0-0110-45e2-bc10-0688fd8b43f0","html_url":"https://github.com/Janko-dev/plogic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Janko-dev%2Fplogic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Janko-dev%2Fplogic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Janko-dev%2Fplogic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Janko-dev%2Fplogic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Janko-dev","download_url":"https://codeload.github.com/Janko-dev/plogic/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253251613,"owners_count":21878533,"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":["logic","repl","rust"],"created_at":"2024-08-03T07:00:58.913Z","updated_at":"2025-05-09T12:32:30.166Z","avatar_url":"https://github.com/Janko-dev.png","language":"Rust","funding_links":[],"categories":["Propositional logic"],"sub_categories":["Libraries"],"readme":"# Plogic\nPropositional logic evaluator and pattern transformer written in Rust. Plogic evaluates logic expressions in a REPL (Read, Execute, Print, Loop) environment and generates every truth table necessary to derive the final truth table result. Another use-case of Plogic is to define and apply pattern rules to transform a expression into another expression. This is a common operation in proof systems. Plogic is a very basic version of a proof system.\n\nThis project is build purely out of recreational and educational purposes.\n\n## Getting started\nTo build the binary executable, `cargo` is required alongside the [Rust](https://www.rust-lang.org/tools/install) installation.\n```\n$ git clone https://github.com/Janko-dev/plogic.git\n$ cd plogic\n$ cargo build --release\n```\nGo to `target/release/` to find the `plogic.exe` (on windows). Run the executable to enter the REPL environment.\n\n``` \n$ cargo run --release\nWelcome to the REPL of Plogic.\nUsage:\n   ----------------------------------------\n   | And oprator      |  '\u0026'  | 'and'     |\n   | Or oprator       |  '|'  | 'or'      |\n   | Not oprator      |  '~'  | 'not'     |\n   | Cond oprator     |  '-\u003e' | 'implies' |\n   | Bi-Cond oprator  | '\u003c-\u003e' | 'equiv'   |\n   ----------------------------------------\n   -----------------------------------------------------------------------\n   | Rule       |  ':='  | identifier-name := lhs-pattern = rhs-pattern  |\n   | binding    | 'rule' | example:   commutative := p \u0026 q = q \u0026 p       |\n   -----------------------------------------------------------------------\n   | Rule       |  '=\u003e'  | inline pattern: A \u0026 B =\u003e p \u0026 q = q \u0026 p        |\n   | Derivation |        | bound pattern : A \u0026 B =\u003e commutative          |\n   -----------------------------------------------------------------------\n   - help:   usage info\n   - ans:    previous answer\n   - toggle: toggle between (T/F) and (1/0) in truth tables\n   - quit:   exit repl\n\u003e p \u0026 q\n---------------------\n[ q ] [ p ] [ p \u0026 q ]\n|---| |---| |-------|\n| 0 | | 0 | |   0   |\n| 1 | | 0 | |   0   |\n| 0 | | 1 | |   0   |\n| 1 | | 1 | |   1   |\n---------------------\n\u003e\n```\n\n## Grammar\nThe following grammar describes the parsing strategy to build the abstract syntax tree. It is noteworthy to mention that the usual mathematical symbols for the operators are not used. Instead, the operators come from the bitwise operators found in various programming languages and optional keywords which may be used for the sake of convenience. The table below shows what each operator means.\n| Operator | Meaning |\n| -------- | ------- |\n| `\u0026` or `and` | The and-operator which says that both left-hand side and right-hand side should evaluate to true, for the result to equal true as well. |\n| `\\|` or `or` | The or-operator which says that either or both left-hand side and right-hand side should evaluate to true, for the result to equal true as well.|\n| `~` or `not` | The negation-operator flips true to false and false to true. |\n| `-\u003e` or `implies` | The conditional implication-operator only evaluates to false when the left-hand side is true and the right-hand side is false, otherwise the result is true. |\n| `\u003c-\u003e` or `equiv` | The biconditional implication-operator only evaluates to true when both left and right hand sides are equal to eachother.|\n\n### Rule-based pattern matching\nFurthermore, to pattern match expressions and transform them into other expressions, the `=\u003e` or `rule` keyword is used after a valid propositional expression. Thereafter must follow a valid left hand-side expression, then a `=`, and then a valid right hand-side expression. Example:\n\n`A \u0026 (B | C) =\u003e p \u0026 (q | r) = (p \u0026 q) | (p \u0026 r)`\n\nThis expression describes the following. The expression `A \u0026 (B | C)` will be matched against the left hand-side after `=\u003e`, i.e. `p \u0026 (q | r)`. Since both have the same pattern, it is a valid match. Thereafter, the right hand-side will be substituted according to the matched symbols in the left hand-side. Therefore, producing the following result:\n\n`(A \u0026 B) | (A \u0026 C)`\n\nIn the case that the left hand-side did not match the expression, an attempt will be made to match the right hand side instead. The same procedure for pattern matching applies, only in reverse. Now, the right hand-side is matched, then substituted in the left hand-side of the given rule. An example will make this more clear. Consider the 'almost' same expression:\n\n`(A \u0026 B) | (A \u0026 C) =\u003e p \u0026 (q | r) = (p \u0026 q) | (p \u0026 r)`\n\nNotice that the left hand-side of the rule portion `p \u0026 (q | r)` does not match the sub-expression `(A \u0026 B) | (A \u0026 C)`. Therefore, the right hand-side will be attempted to match, which produces the result:\n\n`A \u0026 (B | C)`\n\nAside from using inline rule patterns as demonstrated above, which can get convoluted to type if the given rule pattern is used multiple times, there is also the possibility to bind a rule to an identifier name. Consider the following:\n\n`distributive := p \u0026 (q | r) = (p \u0026 q) | (p \u0026 r)`\n\nthe identifier name `distributive` is now bound to the pattern given after `:=`. The pattern identifier can now be used instead. i.e., \n\n`A \u0026 (B | C) =\u003e distributive`\n\nwhich produces the same result as before, i.e., `(A \u0026 B) | (A \u0026 C)`.\n\n``` ebnf\nExpression       = Rule_binding | Rule_apply ;\nRule_binding     = Atom \":=\" Bi_conditional \"=\" Bi_conditional ;\nRule_apply       = Bi_conditional (\"=\u003e\" Bi_conditional \"=\" Bi_conditional)? ;\nBi_conditional   = Conditional ((\"\u003c-\u003e\") Conditional)* ;\nConditional      = Or ((\"-\u003e\") Or)* ;\nOr               = And ((\"|\") And)* ;\nAnd              = Negation ((\"\u0026\") Negation)* ;\nNegation         = \"~\" Negation | Primary ;\nPrimary          = Atom | \"(\" Bi_conditional \")\" ;\nAtom             = [\"a\"-\"z\" | \"A\"-\"Z\"]* ;\n```\n\n## More Examples\n \n```\n\u003e A \u0026 ~A\n-----------------------\n[ A ] [ ~A ] [ A \u0026 ~A ]\n|---| |----| |--------|\n| 0 | | 1  | |   0    |\n| 1 | | 0  | |   0    |\n-----------------------\n```\n```\n\u003e (p implies q) and (q implies p) \n-----------------------------------------------------------------------------------\n[ q ] [ p ] [ (q -\u003e p) ] [ (p -\u003e q) ] [ q -\u003e p ] [ p -\u003e q ] [ (p -\u003e q) \u0026 (q -\u003e p) ]\n|---| |---| |----------| |----------| |--------| |--------| |---------------------|\n| 0 | | 0 | |    1     | |    1     | |   1    | |   1    | |          1          |\n| 1 | | 0 | |    0     | |    1     | |   0    | |   1    | |          0          |\n| 0 | | 1 | |    1     | |    0     | |   1    | |   0    | |          0          |\n| 1 | | 1 | |    1     | |    1     | |   1    | |   1    | |          1          |\n-----------------------------------------------------------------------------------\n```\n```\n\u003e A \u0026 (B | C) =\u003e p \u0026 (q | r) = (p \u0026 q) | (p \u0026 r)\n(A \u0026 B) | (A \u0026 C)\n\u003e ans\n-----------------------------------------------------------\n[ C ] [ B ] [ A ] [ A \u0026 C ] [ A \u0026 B ] [ (A \u0026 B) | (A \u0026 C) ]\n|---| |---| |---| |-------| |-------| |-------------------|\n| 0 | | 0 | | 0 | |   0   | |   0   | |         0         |\n| 0 | | 0 | | 1 | |   0   | |   0   | |         0         |\n| 0 | | 1 | | 0 | |   0   | |   0   | |         0         |\n| 0 | | 1 | | 1 | |   0   | |   1   | |         1         |\n| 1 | | 0 | | 0 | |   0   | |   0   | |         0         |\n| 1 | | 0 | | 1 | |   1   | |   0   | |         1         |\n| 1 | | 1 | | 0 | |   0   | |   0   | |         0         |\n| 1 | | 1 | | 1 | |   1   | |   1   | |         1         |\n-----------------------------------------------------------\n\u003e\n```\n```\n\u003e DeMorgan := ~(p \u0026 q) = ~p | ~q      \n\u003e ~((a -\u003e b) \u0026 ~(b -\u003e c)) =\u003e DeMorgan\n~(a -\u003e b) | ~~(b -\u003e c)\n\u003e toggle\nChanged truthtable symbols from '1'/'0' to 'T'/'F'\n\u003e ans\n-------------------------------------------------------------------------------------------------------------\n[ c ] [ b ] [ a ] [ ~(b -\u003e c) ] [ ~(a -\u003e b) ] [ ~~(b -\u003e c) ] [ b -\u003e c ] [ a -\u003e b ] [ ~(a -\u003e b) | ~~(b -\u003e c) ]\n|---| |---| |---| |-----------| |-----------| |------------| |--------| |--------| |------------------------|\n| F | | F | | F | |     F     | |     F     | |     T      | |   T    | |   T    | |           T            |\n| F | | F | | T | |     F     | |     T     | |     T      | |   T    | |   F    | |           T            |\n| F | | T | | F | |     T     | |     F     | |     F      | |   F    | |   T    | |           F            |\n| F | | T | | T | |     T     | |     F     | |     F      | |   F    | |   T    | |           F            |\n| T | | F | | F | |     F     | |     F     | |     T      | |   T    | |   T    | |           T            |\n| T | | F | | T | |     F     | |     T     | |     T      | |   T    | |   F    | |           T            |\n| T | | T | | F | |     F     | |     F     | |     T      | |   T    | |   T    | |           T            |\n| T | | T | | T | |     F     | |     F     | |     T      | |   T    | |   T    | |           T            |\n-------------------------------------------------------------------------------------------------------------\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJanko-dev%2Fplogic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FJanko-dev%2Fplogic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FJanko-dev%2Fplogic/lists"}