{"id":17692974,"url":"https://github.com/arsalan0c/non-deterministic-source","last_synced_at":"2025-08-12T16:40:05.531Z","repository":{"id":132662692,"uuid":"261506406","full_name":"arsalan0c/non-deterministic-source","owner":"arsalan0c","description":"Metacircular evaluator for a non-deterministic language (based on SICP JS: https://sicp.comp.nus.edu.sg/chapters/85)","archived":false,"fork":false,"pushed_at":"2021-02-07T14:59:54.000Z","size":80,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-30T22:45:27.886Z","etag":null,"topics":["amb","evaluator","metacircular-interpreter","non-deterministic","sicp-js"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"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/arsalan0c.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":"2020-05-05T15:13:01.000Z","updated_at":"2021-02-07T14:59:56.000Z","dependencies_parsed_at":"2023-06-26T01:43:30.020Z","dependency_job_id":null,"html_url":"https://github.com/arsalan0c/non-deterministic-source","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/arsalan0c/non-deterministic-source","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsalan0c%2Fnon-deterministic-source","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsalan0c%2Fnon-deterministic-source/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsalan0c%2Fnon-deterministic-source/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsalan0c%2Fnon-deterministic-source/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arsalan0c","download_url":"https://codeload.github.com/arsalan0c/non-deterministic-source/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arsalan0c%2Fnon-deterministic-source/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270099255,"owners_count":24527027,"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","status":"online","status_checked_at":"2025-08-12T02:00:09.011Z","response_time":80,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["amb","evaluator","metacircular-interpreter","non-deterministic","sicp-js"],"created_at":"2024-10-24T13:07:47.973Z","updated_at":"2025-08-12T16:40:05.497Z","avatar_url":"https://github.com/arsalan0c.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# non-deterministic-source\nMetacircular evaluator for the non-deterministic [Source](https://sicp.comp.nus.edu.sg/source/) 4.3 programming language with John McCarthy's `amb` operator for ambiguous choice. \u003cbr /\u003e\n\nImplementation is in: [evaluator.js](evaluator.js)\n\n## Run using `parse_and_eval`\n\nExample:\n\nFind integers between 0 and 12 (inclusive) that are divisible by 2 or 3.\n\n```js\nparse_and_eval(\"function int_between(low, high) {\\\n                    return low \u003e high ? amb() : amb(low, int_between(low + 1, high));\\\n                }\\\n                function is_even(x) { return (x % 2) === 0;}\\\n                function divisible_by_three(x) { return (x % 3) === 0;}\\\n                let integer = int_between(0, 12);\\\n                require(is_even(integer) || divisible_by_three(integer));\\\n                integer;\");\n\n// result: 0\n```\nSubsequent values can be generated by typing:\n```js\ntry_again(); // result: 2\ntry_again(); // result: 3\ntry_again(); // result: 4\ntry_again(); // result: 6\ntry_again(); // result: 8\ntry_again(); // result: 9\ntry_again(); // result: 10\ntry_again(); // result: 12\ntry_again(); // result: null\n```\n\n### Other quick examples\n```js\n/* SAT solving */\nparse_and_eval(\"\\\nlet P = amb(true, false); \\\nlet Q = amb(true, false); \\\nlet R = amb(true, false); \\\nlet S = amb(true, false); \\\n\\\nlet formula = (P || !Q || R) \u0026\u0026 (!P || Q || S) \u0026\u0026 (Q || !S) \u0026\u0026 (R || S) \u0026\u0026 (P || !R); \\\nrequire(formula === true); \\\n\\\ndisplay('Satisfying Assignment:');\\\ndisplay(P, 'P:'); \\\ndisplay(Q, 'Q:'); \\\ndisplay(R, 'R:'); \\\ndisplay(S, 'S:'); \\\n\");\n\n// use `try_again()` to view all satisfying assignments.\n```\n\n```js\nparse_and_eval(\"const integer_from = n =\u003e amb(n, integer_from(n + 1)); integer_from(1);\");\n// result: 1\ntry_again(); // result: 2\ntry_again(); // result: 3\ntry_again(); // result: 4 ... and so on...\n```\n\n```js\nparse_and_eval(\"const f = amb(1, 2, 3); const g = amb(5, 6, 7); f;\");\n// Result: 1, 1, 1, 2, 2, 2, 3, 3, 3 (use the try_again() function)\n```\n\n```js\nparse_and_eval(\"const f = amb(1, 2, 3); const g = amb(5, 6, 7); g;\");\n// Result: 5, 6, 7, 5, 6, 7, 5, 6, 7 (use the try_again() function)\n```\n\n## Running Tests\n\n1. Copy the code from the following files into the [playground](https://sourceacademy.nus.edu.sg/playground):\n    * `evaluator.js`\n    * `test.js`\n    * `source-test/main.js`\n\n2. Remove one of the two instances of the repeated function `variable_declaration_name` (from `evaluator.js` and `source-test/main.js`)\n\n## Changes from SICP JS\nThis implementation of the evaluator contains several changes from that shown in the textbook. These consist of enhancements as well as bug fixes. \u003cbr /\u003e\n\nIn descending order of complexity:\n* Added logic to correctly evaluate return statements.\n  [#3](https://github.com/anubh-v/non-deterministic-source/pull/3), [#26](https://github.com/anubh-v/non-deterministic-source/pull/26)\n* Added tests for deterministic and non-deterministic functionality. [#8](https://github.com/anubh-v/non-deterministic-source/pull/8)\n* Fixed `execute_application` to ensure that when a function is applied, the extended environment includes\n  names declared in the function body.\n* Solved SICP JS exercise 4.45 by implementing `analyze_require`.\n* Provided a more convenient method of running programs.\n  The textbook implementation accepts programs via a continuously running prompt.\n  In our implementation, users can instead use the `parse_and_eval` and `try_again` functions  to run programs. This allows longer programs to be written easily. [#6](https://github.com/anubh-v/non-deterministic-source/pull/6), [#16](https://github.com/anubh-v/non-deterministic-source/pull/16)\n* Added support for logical operators `\u0026\u0026` and `||`. [#9](https://github.com/anubh-v/non-deterministic-source/pull/9)\n* Added the unary minus operator. [#22](https://github.com/anubh-v/non-deterministic-source/pull/22)\n* Prevented re-assignment to constants. [#13](https://github.com/anubh-v/non-deterministic-source/pull/13)\n* Added support for lists via the `list` function. [#5](https://github.com/anubh-v/non-deterministic-source/pull/5)\n* Improved documentation of some functions. [#11](https://github.com/anubh-v/non-deterministic-source/pull/11)\n\n## Acknowledgements\nThis metacircular evaluator is built based on [SICP JS, Chapter 4.3](https://sicp.comp.nus.edu.sg/chapters/85).\nWe used a metacircular evaluator for Source 1, provided in CS4215 materials, as a starting point for this evaluator.\n\nIt also uses the `parse` function of the [Source Academy](https://github.com/source-academy/js-slang)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farsalan0c%2Fnon-deterministic-source","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farsalan0c%2Fnon-deterministic-source","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farsalan0c%2Fnon-deterministic-source/lists"}