{"id":22824984,"url":"https://github.com/michaeljklein/two_tag","last_synced_at":"2026-01-11T02:42:13.322Z","repository":{"id":256681294,"uuid":"856096284","full_name":"michaeljklein/two_tag","owner":"michaeljklein","description":"An implementation of a bounded 2-tag system in Noir","archived":false,"fork":false,"pushed_at":"2024-09-12T01:33:46.000Z","size":4,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-06T05:32:30.387Z","etag":null,"topics":["noir","tag-system","turing-completeness"],"latest_commit_sha":null,"homepage":"","language":"Noir","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/michaeljklein.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":"2024-09-12T01:33:26.000Z","updated_at":"2024-09-12T17:54:58.000Z","dependencies_parsed_at":"2024-09-12T12:21:00.997Z","dependency_job_id":"19662e22-3c1f-45ce-9d35-cedfbfdd3219","html_url":"https://github.com/michaeljklein/two_tag","commit_stats":null,"previous_names":["michaeljklein/two_tag"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaeljklein%2Ftwo_tag","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaeljklein%2Ftwo_tag/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaeljklein%2Ftwo_tag/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaeljklein%2Ftwo_tag/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaeljklein","download_url":"https://codeload.github.com/michaeljklein/two_tag/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246397055,"owners_count":20770480,"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":["noir","tag-system","turing-completeness"],"created_at":"2024-12-12T17:09:03.196Z","updated_at":"2026-01-11T02:42:13.288Z","avatar_url":"https://github.com/michaeljklein.png","language":"Noir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# two_tag\n\nAn implementation of an arbitrarily-bounded\n[2-tag system](https://en.wikipedia.org/wiki/Tag_system) in Noir\n\n## Why?\n\n2-tag systems are Turing-complete, i.e. they can simulate any deterministic\nprogram, given sufficient space and time.\n\n## Definition of a tag system\n\nAn `m`-tag system is a triplet `(m, A, P)`, where\n\n- `m` is a positive integer, the number of symbols to delete from the FIFO each step\n- `A` is a finite alphabet of symbols\n    + All finite strings of symbols from `A` are called words.\n    + A halting word has `length \u003c m` or begins with the halting symbol\n- `P` is a set of production rules\n    + A production rule assigns a word P(x) to each symbol x in A.\n    + A production on a halting symbol 'H' must be `P(H) = H`\n\nTo evaluate an `m`-tag system:\n1. Begin with an initial word, considered to be the `Tape`\n2. Perform a single step:\n    a. Find the production rule `P` for the first symbol on the `Tape` `x`\n    b. Delete the first `m` symbols on the tape\n    c. Append `P`'s word (`P(x)`) to the `Tape`\n3. If the first symbol of the current word is a halting symbol, stop execution,\n    otherwise go back to step 2.\n4. The final word is considered the output of the system\n\n## Implementation\n\nThe core of the implementation is two structs and a single method:\n\n```rust\n// A bounded FIFO where we can:\n// - Push to the end\n// - Pop from the front\n// - Know:\n//   + Has execution halted?\n//   + Has the amount of space ran out?\n//\n// N is the maximum number of values that can be pushed to the Tape\nstruct Tape\u003clet N: u32\u003e { .. }\n\n// 2-tag program, i.e. a tag system:\n// - The halting symbol is N\n// - Symbols \u003e N are no-ops\n// - The maximum production length is M\n// \n// (N+1), a no-op, can be used to pad rules to length M\nstruct TagSystem\u003clet N: u32, let M: u32\u003e { .. }\n\nimpl\u003clet N: u32, let M: u32\u003e TagSystem\u003cN, M\u003e {\n    // Perform one step of simulating a 2-tag system\n    fn step\u003clet P: u32\u003e(self, tape: \u0026mut Tape\u003cP\u003e) { .. }\n}\n```\n\n## Usage\n\nThe `main()` function currently implements the Collatz function for `25` steps and with a `Tape` size of `64`.\n- You can modify the input by editing [`./Prover.toml`](./Prover.toml)\n\nThe following example can be run with `nargo test`:\n\n```rust\n#[test]\nfn example_two_tag_system() {\n    //     Alphabet: {a,b,c,H}\n    //     Production rules:\n    //          a  --\u003e  ccbaH\n    //          b  --\u003e  cca\n    //          c  --\u003e  cc\n    //\n    // Initial word:                     b  a  a\n    let mut tape: Tape\u003c32\u003e = Tape::new(\u0026[1, 0, 0]);\n\n    // 'X' is the NULL marker, i.e. N+1\n    let tag_system = TagSystem {\n        rules: [\n    //  a -\u003e c  c  b  a  H\n            [2, 2, 1, 0, 3],\n    \n    //  b -\u003e c  c  a  X  X\n            [2, 2, 0, 4, 4],\n    \n    //  c -\u003e a  a  a  X  X\n            [0, 0, 0, 4, 4],\n        ],\n    };\n\n    // Computation\n    //                   100\n    //     Initial word: baa\n    //                     0220\n    //                     acca\n    //                       2022103\n    //                       caccbaH\n    //                         2210322\n    //                         ccbaHcc\n    //                           1032222\n    //                           baHcccc\n    //                             32222220\n    //                             Hcccccca (halt).\n    for _ in 0..25 {\n        tag_system.step(\u0026mut tape);\n        println(tape.show());\n    }\n\n    // The program halted\n    assert(tape.running == false);\n\n    // The program didn't halt because it ran out of space\n    assert(tape.more_space == true);\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaeljklein%2Ftwo_tag","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaeljklein%2Ftwo_tag","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaeljklein%2Ftwo_tag/lists"}