{"id":17633121,"url":"https://github.com/mikhailmints/qunity","last_synced_at":"2025-10-30T02:42:11.455Z","repository":{"id":230986567,"uuid":"779137969","full_name":"mikhailmints/qunity","owner":"mikhailmints","description":"Compilation and simulation of Qunity, a unified language for classical and quantum computing","archived":false,"fork":false,"pushed_at":"2025-03-26T08:39:01.000Z","size":40565,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-31T00:24:06.351Z","etag":null,"topics":["quantum-computing","quantum-programming-language"],"latest_commit_sha":null,"homepage":"","language":"OCaml","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/mikhailmints.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":"2024-03-29T05:56:09.000Z","updated_at":"2025-03-24T12:52:37.000Z","dependencies_parsed_at":"2024-04-11T01:29:37.505Z","dependency_job_id":"58d5e0c0-fffd-4be2-b1c9-76dfd0e051b6","html_url":"https://github.com/mikhailmints/qunity","commit_stats":null,"previous_names":["mikhailmints/qunity-prototypes"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikhailmints%2Fqunity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikhailmints%2Fqunity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikhailmints%2Fqunity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikhailmints%2Fqunity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikhailmints","download_url":"https://codeload.github.com/mikhailmints/qunity/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252588486,"owners_count":21772687,"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":["quantum-computing","quantum-programming-language"],"created_at":"2024-10-23T01:47:29.346Z","updated_at":"2025-10-30T02:42:11.447Z","avatar_url":"https://github.com/mikhailmints.png","language":"OCaml","readme":"# Artifact Overview\n\n## Introduction\n\nThis is the artifact for the paper \"Compositional Quantum Control Flow with Efficient Compilation in Qunity\". This artifact contains the code for the Qunity compiler and interpreter, as well as examples of Qunity code and scripts to run tests and benchmarks. This artifact supports the following claims made in the paper:\n\n- We created the first working implementation of a Qunity compiler while introducing new control flow constructs and a metaprogramming layer.\n- We used differential unit testing to verify the correctness of the circuits output by the compiler.\n- The optimizations introduced in this work significantly improve the qubit and gate counts of the circuits generated by the compiler.\n\n## Hardware Dependencies\n\nNo specialized hardware is required.\n\n## Getting Started Guide\n\nYou should have Docker installed. Download the and unzip the provided file `54.zip`. Then, go to the `qunity` directory. Run the following command (note that the dollar signs throughout these instructions just indicate the start of the command and are not to be entered):\n```bash\n$ docker compose build\n```\nThis should set up all necessary dependencies. It may take about 5 minutes to do this. Then, run the following:\n```bash\n$ docker run -it -v ./qasm_out:/qunity/qasm_out -v ./diagrams:/qunity/diagrams qunity:latest\n```\nThe `-v` flags create a bind mount linking your host machine and the Docker container, so that you can directly see the compiled files and generated images in the `qasm_out` and `diagrams` directories on your host machine. If you are using Windows or otherwise if you don't see these files appearing on your host machine, you might need to use absolute paths instead of relative paths in the above command. For instance, if you put the `qunity` folder on your desktop, then the command would have to be\n```bash\n$ docker run -it -v C:/Users/user/Desktop/qunity/qasm_out:/qunity/qasm_out -v C:/Users/user/Desktop/qunity/diagrams:/qunity/diagrams qunity:latest\n```\n\nThis should start a Docker container. Now, to test if everything works correctly, run the following in the container:\n```bash\n$ ./qunity-compile examples/bit0.qunity --analyze\n```\nThe expected output is the following:\n```\nStarting compiler                       \nPreprocessing\nTypechecking\nCompiling to QASM\nPostprocessing\n.\nOutputting to file\nCompilation done\nqasm_out/bit0.qasm\n\nStarting analysis script\nImporting libraries\nAnalyzing file qasm_out/bit0.qasm\nLoading circuit\nDrawing circuit\nDiagram in diagrams/circuits/bit0.png\nTranspiling circuit\nQubits: 1\nDepth: 1\nGates: 1\nSimulating circuit\nResults in diagrams/sim_results/bit0_sim_results.png\n```\n\nIf you get permission errors when running the above, try running the following in the container:\n```bash\n$ sudo chmod -R 777 .\n```\n\nYou should now be able to see the compiled QASM file in `qasm_out/bit0.qasm`. You should also be able to see the generated circuit diagram in `diagrams/circuits` and `diagrams/sim_results`. All subsequent commands in the instructions should be run inside the Docker container.\n\n## Step by Step Instructions\n\n### Instructions for Reproducing Table 3\n\nTo reproduce the benchmark results from Table 3 and verify the circuit efficiency claim, you can simply run:\n```bash\n$ ./benchmarks\n```\nThis script should take approximately 10 minutes to run. It will output the qubit and gate counts for the unoptimized and optimized Qunity compiler, as well as the reference Qiskit implementation when available. It will also draw and simulate the optimized Qunity and Qiskit circuits, and you can check that the generated results histograms look nearly identical (with minor differences due to random sampling), although these histograms are not very useful for some of the examples where the measurement outcomes are uniform over a large number of states.\n\nNote that the evaluation of the unoptimized Grover's algorithm example should time out as the generated circuit is too large - the number of qubits can be confirmed by looking at the generated `qasm_out/grover_unoptimized.qasm` file. The order finding example will not have a Qiskit implementation and is not supported by the unoptimized compiler, and the list sum oracle example is also not supported by the unoptimized compiler.\n\n### Running the Tests\n\nTo run the tests, use the following:\n```bash\n$ ./run-tests\n```\nThis should take approximately 1 minute to run. This script runs some basic unit tests, and also performs the differential unit testing mentioned in Section 7. The results of this can be seen in the tests labeled `compile_file_correctness`. These run the Qunity compiler on the listed files and simulate the resulting circuit, comparing the result to the output of the Qunity interpreter. For files that output circuits too large to simulate classically, the compiler is run without comparing the results, just to check that no exceptions are raised in the compilation process - these tests are labeled `compile_file_no_error`. All tests should say \"passed\".\n\n## Reusability Guide\n\nThis artifact provides tools to compile and run user-provided Qunity programs, ensuring its reusability. In this section, we describe the structure of the artifact and provide instructions for using these tools.\n\n### File Structure\n\nThe main parts of the code for the Qunity parser, preprocessor, typechecker, compiler, and interpreter are found in `lib`. The `bin` directory contains driver files for running the compiler and interpreter. The `examples` directory contains many examples of Qunity code, which are used for testing. The `qunitylib` directory contains the Qunity standard library, `stdlib.qunity`. The `test` directory contains files used for testing. The Bash and Python scripts in the outer directory can be used to more conveniently run the code and analyze, draw, and simulate the resulting circuits with Qiskit.\n\n### Running the Qunity Interpreter\n\nTo run a single program using the interpreter:\n```bash\n$ ./qunity-run \u003cfilename\u003e\n```\n\nTo start an interactive Qunity REPL:\n```bash\n$ ./qunity-interact\n```\nYou can enter Qunity expressions or create definitions in the interpreter. Inputs should be terminated by a double semicolon: `;;`. You can exit the REPL by typing `%quit;;`. Here is an example of a REPL session:\n```\n$ ./qunity-interact\n\u003cqunity\u003e $0;;\nExpression type: Bit\nIsometry: true\nPure semantics:\n|0\u003e\n\nMixed semantics:\n|0\u003e\u003c0|\n\nPossible measurement outcomes:\nProbability 1.000000: $0\n\n\u003cqunity\u003e def @share : Bit -\u003e Bit * Bit := lambda x -\u003e (x, x) end;;\n\u003cqunity\u003e @share($plus);;\nExpression type: Bit * Bit\nIsometry: true\nPure semantics:\n 0.707+0.000i \n 0.000+0.000i \n 0.000+0.000i \n 0.707+0.000i \n\nMixed semantics:\n 0.500+0.000i  0.000+0.000i  0.000+0.000i  0.500+0.000i \n 0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i \n 0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i \n 0.500+0.000i  0.000+0.000i  0.000+0.000i  0.500+0.000i \n\nPossible measurement outcomes:\nProbability 0.500000: ($0, $0)\nProbability 0.500000: ($1, $1)\n\n\u003cqunity\u003e $ListEmpty{2, Bit} |\u003e @list_append_const{2, Bit, $0} |\u003e @list_append_const{2, Bit, $plus};;\nExpression type: List{2, Bit}\nIsometry: false\nPure semantics:\nNone\n\nMixed semantics:\n 0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i \n 0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i \n 0.000+0.000i  0.000+0.000i  0.500+0.000i  0.500+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i \n 0.000+0.000i  0.000+0.000i  0.500+0.000i  0.500+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i \n 0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i \n 0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i \n 0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i  0.000+0.000i \n\nPossible measurement outcomes:\nProbability 0.500000: @ListCons{2, Bit}(($0, @ListCons{1, Bit}(($0, $ListEmpty{0, Bit}))))\nProbability 0.500000: @ListCons{2, Bit}(($0, @ListCons{1, Bit}(($1, $ListEmpty{0, Bit}))))\n```\nThe interpreter will output the type of the provided expression, whether or not it is considered an isometry by the typechecker, the computed semantics, and the possible measurement outcomes with their probabilities. The operator semantics is represented in matrix form, with pure semantics written in bra-ket notation if the matrix is internally represented as sparse. The first prompt given in the above example simply prepared a $|0\\rangle$ state. The next two prompts defined a \"share\" operation and used it to prepare a Bell state by sharing a $|+\\rangle$ state in the computational basis. The last prompt above demonstrated the use of Qunity's list data structure, appending $|0\\rangle$ and $|+\\rangle$ to an empty list of capacity 2: the measurement outcomes show that the second element is equally likely to be measured as $|0\\rangle$ or $|1\\rangle$.\n\n### Running the Qunity Compiler\n\nTo compile a single Qunity file into OpenQASM 3:\n```bash\n$ ./qunity-compile \u003cfilename\u003e [-o \u003cout_filename\u003e] [--analyze] [--unoptimized] [--nopost] [--img-format={png|jpeg|svg}]\n```\nIf no output filename is specified, by default it goes in the `qasm_out` directory. If `--analyze` is used, a circuit diagram will be generated, and the circuit will be simulated using Qiskit. If `--unoptimized` is used, the old version of the compiler will be run (does not support features present in some of the examples). If `--nopost` is used, postprocessing optimizations are not applied. The `--img-format` option allows the user to specify the desired format of the generated circuit diagram and results histogram images, which can be `png` (default), `jpeg`, or `svg`.\n\nFor instance:\n```\n$ ./qunity-compile examples/grover.qunity --analyze\nStarting compiler                     \nPreprocessing\nTypechecking\nCompiling to QASM\nPostprocessing\n...\nOutputting to file\nCompilation done\nqasm_out/grover.qasm\n\nStarting analysis script\nImporting libraries\nAnalyzing file qasm_out/grover.qasm\nLoading circuit\nDrawing circuit\nDiagram in diagrams/circuits/grover.png\nTranspiling circuit\nQubits: 7\nDepth: 614\nGates: 760\nSimulating circuit\nResults in diagrams/sim_results/grover_sim_results.png\n```\nThe corresponding files in the `diagrams` directory should then display the generated circuit diagram and the simulation results histogram. The resulting histogram should have a high frequency associated with the bit string `01100`, which is the \"correct answer\" for the oracle in this example, and a low frequency for all other bit strings.\n\n\u003e **Note on interpreting the outputs**: While in the above example, it is clear that the bit string `01100` corresponds to `($0, ($1, ($1, ($0, ($0, ())))))` in the Qunity source code, the encoding of Qunity types into bit strings when considering variant types may not be as obvious. If a type has two constructors taking types `'a` and `'b`, then the first bit (or qubit) in the encoding specifies which constructor is used, and the rest of the bits contain either a value of type `'a` or one of type `'b`. If one type is larger than the other, the unused bits must be zero in a valid encoding. Data types with multiple constructors are treated as a sum type of the first constructor with the remaining ones. So, for instance, when you compile and simulate `examples/equal_superpos_trit.qunity`, the results should show an equal frequency of `00`, `10`, and `11`, since these correspond to `$Nothing{Bit}`, `@Just{Bit}($0)`, and `@Just{Bit}($1)` respectively. There is no `01`, since that would be an invalid encoding for the type `Maybe{Bit}`. Similarly, for `examples/grover_with_lists.qunity`, the bit strings that have nonzero frequencies correspond to the lists `[]`, `[0]`, `[0, 0]`, `[0, 1]`, `[1]`, `[1, 0]`, and `[1, 1]`. Those with the higher frequency have an odd number of ones.\n\nTo compile all the example Qunity programs:\n```bash\n$ ./compile-all-examples [--analyze] [--unoptimized] [--nopost] [--img-format={png|jpeg|svg}]\n```\nNote that while running `./compile-all-examples` should only take about 20 seconds, running it with `--analyze` to generate all diagrams and perform all simulations can take approximately 5 minutes. Several of the examples are explicitly skipped during this process because they take too long to simulate.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikhailmints%2Fqunity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikhailmints%2Fqunity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikhailmints%2Fqunity/lists"}