{"id":16411160,"url":"https://github.com/phoe/amb","last_synced_at":"2026-03-02T13:33:51.863Z","repository":{"id":111724036,"uuid":"441483238","full_name":"phoe/amb","owner":"phoe","description":"An implementation of John McCarthy's ambiguous operator in portable Common Lisp.","archived":false,"fork":false,"pushed_at":"2022-12-24T23:52:25.000Z","size":42,"stargazers_count":38,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-01-06T03:24:01.083Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Common Lisp","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/phoe.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":"2021-12-24T14:15:55.000Z","updated_at":"2024-11-02T22:01:56.000Z","dependencies_parsed_at":null,"dependency_job_id":"07e10d8c-0fee-4bce-b295-452f87f591be","html_url":"https://github.com/phoe/amb","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/phoe%2Famb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoe%2Famb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoe%2Famb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phoe%2Famb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phoe","download_url":"https://codeload.github.com/phoe/amb/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240416360,"owners_count":19797801,"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-11T06:44:41.471Z","updated_at":"2026-03-02T13:33:46.816Z","avatar_url":"https://github.com/phoe.png","language":"Common Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AMB\n\nThis is an implementation of John McCarthy's ambiguous operator written in\nportable Common Lisp.\n\nThe `amb` operator implements a system which is capable of automatically\nsearching for a set of values for variables (henceforth called *ambiguous\nvariables*) for which a set of constraints is satisfied. The operator and its\nexample use are described in detail in\n[Structure and Interpretation of Computer Programs Chapter 4.3 (Nondeterministic\nComputing)](https://sarabander.github.io/sicp/html/4_002e3.xhtml#g_t4_002e3).\n\nSee the [manual](doc/MANUAL.md) and the [SICP test cases](t/test-sicp.lisp) for\nexamples.\n\n## API\n\nThe direct API consists of two macros, `amb` and `constrain`, which,\nrespectively, bind ambiguous variables and place constraints which, if not met,\ncause the code to backtrack and select the next combination of values to try.\n\nIf no match is found, a warning `amb-failure` might be signaled. The `amb` stack\nfor which no match was found can be retrieved from that condition via the\n`amb-failure-stack` reader function.\n\n* Macro **`AMB`**\n  * Binds one or more ambiguous variables and establishes a dynamic\n    environment in which it is possible to place constraints via the\n    `constrain` macro. If all of the constraints are satisfied and the body\n    evaluates to a true value, it is returned; otherwise, a next set of values\n    is tried for a match. If `amb` runs out of combinations to try,\n    `amb-failure` might be signaled depending on the value of `:signalp` option.\n  * Syntax: `(amb bindings-and-options \u0026body body)`\n    * `bindings-and-options`: a list of bindings and options.\n      * Binding syntax: `(variable values \u0026key shufflep)`\n        * `variable` must be a symbol naming a variable,\n        * `values` is an expression that is evaluated to produce a list of\n          values that will be tried in order to find a match.\n        * `shufflep`, if true, randomizes the order in which the values will be\n          tried. Default behavior is no randomization.\n      * Option **`:STACK`**\n        * Sets the stack for the given `amb` invocation. The default is the symbol\n          `amb-stack`, denoting the default stack.\n        * Syntax: `(:stack STACK-NAME)`, where `STACK-NAME` is a\n          symbol.\n      * Option **`:SIGNALP`**\n        * Sets the warning mode for the given `amb` invocation: no signaling in\n          case of `nil`, or using, respectively, `signal`, `warn`, or `error` to\n          signal the `amb-failure` warning.\n        * Syntax: `(:signalp MODE)`, where `MODE` is one of `nil`, `signal`,\n          `warn`, or `error`.\n* Macro **`CONSTRAIN`**\n  * Syntax: `(constrain constraint \u0026optional stack)`\n    * `constraint` is an expression that is evaluated to produce a boolean\n      value. If it is true, it is returned; otherwise, it causes the program to\n      backtrack in order to select the next set of values to try.\n    * `stack` selects the stack for the given `amb` invocation. The default is a\n    default stack.\n* Condition Type **`AMB-FAILURE`**\n  * The warning signaled whenever the outermost `amb` form fails to find a match\n    for its contents.\n  * Reader: **`AMB-FAILURE-STACK`** - returns the `amb` stack for which no match\n  was found.\n\n## Differences from Screamer\n\n[Screamer](https://github.com/nikodemus/screamer/) offers a much more complete\nand optimized environment for writing nondeterministic Common Lisp, at a cost\nof being big in terms of lines of code and complexity, as well as needing to\nshadow many symbols of standard Common Lisp.\n\nThis implementation of `amb` is meant to achieve the converse: it should be easy\nto understand and its code is meant to fit on a single sheet of paper.\n\nTherefore: for complex and/or production uses, please consider using Screamer.\nFor simple tasks and working with SICP, this `amb` implementation should be a\ndecent fit.\n\n## License\n\nMIT.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoe%2Famb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphoe%2Famb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphoe%2Famb/lists"}