{"id":17361451,"url":"https://github.com/alexandergrooff/constraint-handling-rules","last_synced_at":"2026-01-07T01:32:43.302Z","repository":{"id":116377551,"uuid":"56841821","full_name":"AlexanderGrooff/Constraint-Handling-Rules","owner":"AlexanderGrooff","description":null,"archived":false,"fork":false,"pushed_at":"2016-07-04T18:09:52.000Z","size":173,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-02-01T20:26:26.958Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Prolog","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/AlexanderGrooff.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":"2016-04-22T08:59:29.000Z","updated_at":"2016-07-04T18:11:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"633e8220-fcdf-47a3-ae50-5884bec7feaf","html_url":"https://github.com/AlexanderGrooff/Constraint-Handling-Rules","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/AlexanderGrooff%2FConstraint-Handling-Rules","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderGrooff%2FConstraint-Handling-Rules/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderGrooff%2FConstraint-Handling-Rules/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexanderGrooff%2FConstraint-Handling-Rules/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlexanderGrooff","download_url":"https://codeload.github.com/AlexanderGrooff/Constraint-Handling-Rules/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245887124,"owners_count":20688793,"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":[],"created_at":"2024-10-15T19:33:30.183Z","updated_at":"2026-01-07T01:32:43.277Z","avatar_url":"https://github.com/AlexanderGrooff.png","language":"Prolog","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Implementation details\n\nThis Prolog implementation solves a given Prolog query `?- \u003c...\u003e.` given zero or many facts `\u003c...\u003e.`, and/or horn clauses `\u003c...\u003e :- \u003c...\u003e.`. It answers `true` or `false`, along with variable equalities, if found in the form `X1 = \u003c...\u003e,...,Xn = \u003c...\u003e`.\n\n## Syntax\n\nThe solver requires an input file in the form: `Statement* Query`, where:\n```\nStatement ::= \u003cDefinable\u003e :- \u003cCallable\u003e.\nStatement ::= \u003cDefinable\u003e.\nQuery ::= ?- \u003cCallable\u003e.\n```\nThe relation between `Definable` and `Callable` is a strict inclusion, such that `Callable ::= Definable` (`Definable` is a subset of `Callable`), but not reversed. `Definable` can only be rewritten to a Prolog atom and a Compound Term with one or many `Term`s as arguments. `Callable` additionally allows:\n* Conjunction of 2 `Callable`s `,/2`\n* Disjunction of 2 `Callable`s `;/2`\n* Negation of 1 `Callable` `\\+/1`\n* Explicit Unification of 2 `Term`s `=/2`\n* Term equality `==/2`\n* Arithmetic comparisons\n* `is/2` evaluations\n`Callable` does not allow basic expressions such as numbers, strings, arithmetic expressions and variables. Only the `Term` can be rewritten to those syntactic elements.\n\n## Transformation Strategies\n\n`trans/evaluation.str` contains the most important Stratego strategies for solving Prolog queries. The `\u003cevaluate-full\u003e` strategy takes the `Statement`s and query, desugars them and then delegate the solving to the `\u003cevaluate\u003e` strategy.\nThe `\u003cevaluate\u003e` strategy loops over all `Statement`s in the knowledge base and tries to succeed the following: First `\u003cunify\u003e` the query with the left-hand side of the horn-clause. Then `\u003csubstitute-all\u003e` on the right-hand side of the horn-clause. Recursively apply `\u003cevaluate\u003e` and return its result. For conjunctions `,/2`, disjunctions `;/2`, and negations `\\+/1` special rewrite rules are followed. When `\u003cevaluate\u003e` finds one of the operators `=/2`, `==/2`, one of the arithmetic comparisons, or `is/2`, the knowledge base is not consulted, but instead the operation is invoked using Stratego. The `=/2`, for example simply applies `\u003cunify\u003e` to both ends of the operator, then checks for consistency using `\u003csubstitute-all\u003e`.\nThe `\u003cunify\u003e` strategy succeeds only when the two given terms are unifyable. It also returns a list of equalities of the Prolog variables it found. `\u003cunify\u003e` recursively applies to inner terms of lists and compound terms. `\u003cunify\u003e` with at least one variable and some other term always succeeds by returning the equality between that variable and that term. `\u003cunify\u003e` with two identical terms also succeeds. `\u003cunify\u003e` does not check consistency between the resulting equalities. This is instead done by `\u003csubstitute-all\u003e`.\nThe `\u003csubstitute-all\u003e` strategy takes a triple consisting of:\n1. A (optional) right hand side of a horn clause\n2. The list of equalities that need to be substituted and checked for consistency\n3. A list of free variables whose equalities we want to preserve\nAll equalities are in the form `\u003cV : Variable\u003e = \u003cT : Term\u003e`. All occurrences of `V` in the body (1.), and the right-hand sides of the equalities (2. and 3.) are substituted by `T`. If there are other equalities with the same variable in the left-hand side, say `V = \u003cT' : Term\u003e`, then `\u003cunify\u003e` is applied between `T` and `T'` with any resulting equalities added to (2.). After this is done the equality `V = T` is removed from the list. If `V` is listed in (3.) as needs to be preserved, then the equality is added into (3.). `\u003csubstitute-all\u003e` then continues with the other equalities in (2.) until that list is empty.\n\n# Future Work\n\n## Disjunction Answers\n\nAn important feature which has not yet been implemented is the possibility of disjunction in answers. This should occur when a query evaluates to `true` and there are multiple possible assignments to the free (query) variables. An example:\n```\na(x1, x2).\na(x3, x4).\n\n?- a(V1, V2).\n```\nThe current implementation halts when it has found the first satisfying assigment:\n```\ntrue.\nV1 = x1, V2 = x2.\n```\nA correct implementation should result in:\n```\ntrue.\nV1 = x1, V2 = x2;\nV1 = x3, V2 = x4.\n```\n\n## Cut\n\nAnother important feature that has not been implemented is the cut operator `!/1`. This gives the programmer control over when the engine should stop searching for satisfying asssignments.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandergrooff%2Fconstraint-handling-rules","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexandergrooff%2Fconstraint-handling-rules","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandergrooff%2Fconstraint-handling-rules/lists"}