diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
new file mode 100644
index 000000000..92ba2c945
--- /dev/null
+++ b/.github/workflows/pages.yml
@@ -0,0 +1,82 @@
+# Deploys the site in site/ to GitHub Pages: the landing page plus the
+# playground, which runs AutoQ compiled to WebAssembly (wasm/build.sh).
+#
+# One-time setup before the first run: in the repository settings, open
+# Settings -> Pages -> Build and deployment and set Source to "GitHub Actions".
+# Without that, the Configure Pages step fails. (Passing `enablement: true` to
+# actions/configure-pages would enable Pages automatically, but it needs a
+# token with admin rights; the default GITHUB_TOKEN does not have them.)
+#
+# After the first deploy, compare the page_url printed by the deploy step with
+# the canonical and og: URLs in site/index.html (https://fmlab-iis.github.io/AutoQ/).
+#
+# The first run builds Z3 and the ANTLR runtime for WebAssembly, which takes
+# a while; later runs restore them from the cache.
+name: Deploy landing page
+
+on:
+ push:
+ branches: [main]
+ paths:
+ - "site/**"
+ - "wasm/**"
+ - "src/**"
+ - "include/**"
+ - "cli/**"
+ - "CMakeLists.txt"
+ - ".github/workflows/pages.yml"
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+concurrency:
+ group: "pages"
+ cancel-in-progress: false
+
+env:
+ EMSDK_VERSION: "6.0.12"
+
+jobs:
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0 # autoq -v reports the commit from git describe
+
+ - name: Install Boost headers
+ run: sudo apt-get update && sudo apt-get install -y libboost-dev
+
+ - name: Install Emscripten
+ run: |
+ git clone --depth 1 https://github.com/emscripten-core/emsdk.git "$RUNNER_TEMP/emsdk"
+ "$RUNNER_TEMP/emsdk/emsdk" install "$EMSDK_VERSION"
+ "$RUNNER_TEMP/emsdk/emsdk" activate "$EMSDK_VERSION"
+
+ - name: Cache Z3 and ANTLR for WebAssembly
+ uses: actions/cache@v4
+ with:
+ path: build-wasm/deps
+ key: wasm-deps-${{ env.EMSDK_VERSION }}-${{ hashFiles('wasm/build.sh') }}
+
+ - name: Build the playground (AutoQ to WebAssembly)
+ run: |
+ source "$RUNNER_TEMP/emsdk/emsdk_env.sh"
+ wasm/build.sh site/playground
+
+ - name: Configure Pages
+ uses: actions/configure-pages@v5
+ - name: Upload site
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: site
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4
diff --git a/.gitignore b/.gitignore
index ec540a9cd..f1fe076e9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,8 @@ POPL24/TABLES/Algorithms/*.pdf
POPL24/TABLES/Algorithms/*.tex
POPL24/TABLES/Algorithms/*.log
POPL24/TABLES/Algorithms/*.aux
-benchmark*/_others/**
\ No newline at end of file
+benchmark*/_others/**
+# WebAssembly build (wasm/build.sh); the playground binaries are built in CI
+build-wasm/
+site/playground/autoq.js
+site/playground/autoq.wasm
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3da6d74c4..e8c827082 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -158,17 +158,26 @@ include(CTest)
# DEPENDENCIES
##############################################################################
-# Boost
-set(Boost_USE_MULTITHREADED OFF)
-find_package(Boost 1.71.0...1.89.0 CONFIG COMPONENTS # 1.89.0 is for macOS on GitHub CI
- filesystem
-# system
- unit_test_framework
- REQUIRED)
-# IMPORTANT CHANGE: https://github.com/facebook/folly/issues/2489
-# Boost.System has been header-only since 1.69.
-# If someone increases minimum Boost to 1.71 then can just remove the system component.
-include_directories(${Boost_INCLUDE_DIRS})
+if (EMSCRIPTEN)
+ # WebAssembly build (wasm/build.sh). Only header-only parts of Boost are
+ # used, and Z3 and the ANTLR runtime are prebuilt static libraries.
+ set(AUTOQ_WASM_BOOST_INCLUDE "" CACHE PATH "Directory containing the boost/ headers")
+ set(AUTOQ_WASM_Z3_LIB "" CACHE FILEPATH "Z3 static library built with Emscripten")
+ set(AUTOQ_WASM_ANTLR4_LIB "" CACHE FILEPATH "ANTLR4 C++ runtime static library built with Emscripten")
+ include_directories(${AUTOQ_WASM_BOOST_INCLUDE})
+else()
+ # Boost
+ set(Boost_USE_MULTITHREADED OFF)
+ find_package(Boost 1.71.0...1.89.0 CONFIG COMPONENTS # 1.89.0 is for macOS on GitHub CI
+ filesystem
+ # system
+ unit_test_framework
+ REQUIRED)
+ # IMPORTANT CHANGE: https://github.com/facebook/folly/issues/2489
+ # Boost.System has been header-only since 1.69.
+ # If someone increases minimum Boost to 1.71 then can just remove the system component.
+ include_directories(${Boost_INCLUDE_DIRS})
+endif()
include_directories(../include/z3)
# Doxygen - voluntary
@@ -189,6 +198,8 @@ endif()
# Process subdirectories
add_subdirectory(src)
add_subdirectory(cli)
-add_subdirectory(unit_tests)
+if (NOT EMSCRIPTEN)
+ add_subdirectory(unit_tests)
+endif()
# add_subdirectory(parametric)
# add_subdirectory(tests)
diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt
index 5710e727e..cf2aef233 100644
--- a/cli/CMakeLists.txt
+++ b/cli/CMakeLists.txt
@@ -34,3 +34,23 @@ endforeach()
if (MAKE_STATIC_AUTOQ)
SET(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -static")
endif()
+
+if (EMSCRIPTEN)
+ # WebAssembly build (wasm/build.sh): an ES module exporting createAutoQ().
+ # The playground (site/playground) writes the input files into the
+ # in-memory filesystem and runs main() through callMain() on a fresh
+ # instance per run.
+ target_link_options(autoq PRIVATE
+ -fwasm-exceptions
+ -sMODULARIZE=1
+ -sEXPORT_ES6=1
+ -sEXPORT_NAME=createAutoQ
+ -sENVIRONMENT=web,worker,node
+ -sINVOKE_RUN=0
+ -sEXIT_RUNTIME=1
+ -sALLOW_MEMORY_GROWTH=1
+ -sMAXIMUM_MEMORY=4GB
+ -sSTACK_SIZE=8MB
+ -sFORCE_FILESYSTEM=1
+ -sEXPORTED_RUNTIME_METHODS=callMain,FS)
+endif()
diff --git a/cli/autoq.cc b/cli/autoq.cc
index bbcb557eb..77684e1ec 100644
--- a/cli/autoq.cc
+++ b/cli/autoq.cc
@@ -234,7 +234,9 @@ static void run_verification(const std::string& pre, const std::string& post, co
int main(int argc, char **argv) {
try {
// set_timeout(600);
+#ifndef __EMSCRIPTEN__ // WebAssembly has no floating-point exception traps
feenableexcept(FE_ALL_EXCEPT & ~FE_INEXACT);
+#endif
CLI::App app{"AutoQ 2.0: An automata-based C++ tool for quantum program verification."};
std::string pre, circuit, post, circuit1, circuit2;
diff --git a/site/.nojekyll b/site/.nojekyll
new file mode 100644
index 000000000..e69de29bb
diff --git a/site/assets/apple-touch-icon.png b/site/assets/apple-touch-icon.png
new file mode 100644
index 000000000..3d3ac8b3f
Binary files /dev/null and b/site/assets/apple-touch-icon.png differ
diff --git a/site/assets/favicon-32.png b/site/assets/favicon-32.png
new file mode 100644
index 000000000..f8eadf9e8
Binary files /dev/null and b/site/assets/favicon-32.png differ
diff --git a/site/assets/favicon.svg b/site/assets/favicon.svg
new file mode 100644
index 000000000..568d177e9
--- /dev/null
+++ b/site/assets/favicon.svg
@@ -0,0 +1,11 @@
+
diff --git a/site/assets/fonts/OFL.txt b/site/assets/fonts/OFL.txt
new file mode 100644
index 000000000..cd8eb940f
--- /dev/null
+++ b/site/assets/fonts/OFL.txt
@@ -0,0 +1,98 @@
+The web fonts in this folder are subsets served by Google Fonts and are
+used under the SIL Open Font License, Version 1.1:
+
+Bodoni Moda: Copyright 2020 The Bodoni Moda Project Authors (https://github.com/indestructible-type/Bodoni)
+Instrument Sans: Copyright 2022 The Instrument Sans Project Authors (https://github.com/Instrument/instrument-sans)
+JetBrains Mono: Copyright 2020 The JetBrains Mono Project Authors (https://github.com/JetBrains/JetBrainsMono)
+Noto Sans Math: Copyright 2022 Google LLC. All Rights Reserved.
+Noto Sans Mono: Copyright 2022 The Noto Project Authors (https://github.com/notofonts/latin-greek-cyrillic)
+
+The license is copied below, and is also available with a FAQ at:
+https://openfontlicense.org
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/site/assets/fonts/bodoni-moda-italic-latin-ext.woff2 b/site/assets/fonts/bodoni-moda-italic-latin-ext.woff2
new file mode 100644
index 000000000..62606666e
Binary files /dev/null and b/site/assets/fonts/bodoni-moda-italic-latin-ext.woff2 differ
diff --git a/site/assets/fonts/bodoni-moda-italic-latin.woff2 b/site/assets/fonts/bodoni-moda-italic-latin.woff2
new file mode 100644
index 000000000..3c7c2ec8a
Binary files /dev/null and b/site/assets/fonts/bodoni-moda-italic-latin.woff2 differ
diff --git a/site/assets/fonts/bodoni-moda-italic-math.woff2 b/site/assets/fonts/bodoni-moda-italic-math.woff2
new file mode 100644
index 000000000..9916a527e
Binary files /dev/null and b/site/assets/fonts/bodoni-moda-italic-math.woff2 differ
diff --git a/site/assets/fonts/bodoni-moda-italic-symbols.woff2 b/site/assets/fonts/bodoni-moda-italic-symbols.woff2
new file mode 100644
index 000000000..69f166727
Binary files /dev/null and b/site/assets/fonts/bodoni-moda-italic-symbols.woff2 differ
diff --git a/site/assets/fonts/bodoni-moda-normal-latin-ext.woff2 b/site/assets/fonts/bodoni-moda-normal-latin-ext.woff2
new file mode 100644
index 000000000..c370e140a
Binary files /dev/null and b/site/assets/fonts/bodoni-moda-normal-latin-ext.woff2 differ
diff --git a/site/assets/fonts/bodoni-moda-normal-latin.woff2 b/site/assets/fonts/bodoni-moda-normal-latin.woff2
new file mode 100644
index 000000000..7905afa99
Binary files /dev/null and b/site/assets/fonts/bodoni-moda-normal-latin.woff2 differ
diff --git a/site/assets/fonts/bodoni-moda-normal-math.woff2 b/site/assets/fonts/bodoni-moda-normal-math.woff2
new file mode 100644
index 000000000..fb0b95722
Binary files /dev/null and b/site/assets/fonts/bodoni-moda-normal-math.woff2 differ
diff --git a/site/assets/fonts/bodoni-moda-normal-symbols.woff2 b/site/assets/fonts/bodoni-moda-normal-symbols.woff2
new file mode 100644
index 000000000..07d14497a
Binary files /dev/null and b/site/assets/fonts/bodoni-moda-normal-symbols.woff2 differ
diff --git a/site/assets/fonts/instrument-sans-italic-latin-ext.woff2 b/site/assets/fonts/instrument-sans-italic-latin-ext.woff2
new file mode 100644
index 000000000..5e3f41eb9
Binary files /dev/null and b/site/assets/fonts/instrument-sans-italic-latin-ext.woff2 differ
diff --git a/site/assets/fonts/instrument-sans-italic-latin.woff2 b/site/assets/fonts/instrument-sans-italic-latin.woff2
new file mode 100644
index 000000000..b10fd1c00
Binary files /dev/null and b/site/assets/fonts/instrument-sans-italic-latin.woff2 differ
diff --git a/site/assets/fonts/instrument-sans-normal-latin-ext.woff2 b/site/assets/fonts/instrument-sans-normal-latin-ext.woff2
new file mode 100644
index 000000000..0ea0da04c
Binary files /dev/null and b/site/assets/fonts/instrument-sans-normal-latin-ext.woff2 differ
diff --git a/site/assets/fonts/instrument-sans-normal-latin.woff2 b/site/assets/fonts/instrument-sans-normal-latin.woff2
new file mode 100644
index 000000000..8611e41b1
Binary files /dev/null and b/site/assets/fonts/instrument-sans-normal-latin.woff2 differ
diff --git a/site/assets/fonts/jetbrains-mono-italic-greek.woff2 b/site/assets/fonts/jetbrains-mono-italic-greek.woff2
new file mode 100644
index 000000000..bd07500ce
Binary files /dev/null and b/site/assets/fonts/jetbrains-mono-italic-greek.woff2 differ
diff --git a/site/assets/fonts/jetbrains-mono-italic-latin-ext.woff2 b/site/assets/fonts/jetbrains-mono-italic-latin-ext.woff2
new file mode 100644
index 000000000..c88b32dd9
Binary files /dev/null and b/site/assets/fonts/jetbrains-mono-italic-latin-ext.woff2 differ
diff --git a/site/assets/fonts/jetbrains-mono-italic-latin.woff2 b/site/assets/fonts/jetbrains-mono-italic-latin.woff2
new file mode 100644
index 000000000..3d3c5d77e
Binary files /dev/null and b/site/assets/fonts/jetbrains-mono-italic-latin.woff2 differ
diff --git a/site/assets/fonts/jetbrains-mono-normal-greek.woff2 b/site/assets/fonts/jetbrains-mono-normal-greek.woff2
new file mode 100644
index 000000000..a53d52d6d
Binary files /dev/null and b/site/assets/fonts/jetbrains-mono-normal-greek.woff2 differ
diff --git a/site/assets/fonts/jetbrains-mono-normal-latin-ext.woff2 b/site/assets/fonts/jetbrains-mono-normal-latin-ext.woff2
new file mode 100644
index 000000000..82f96681c
Binary files /dev/null and b/site/assets/fonts/jetbrains-mono-normal-latin-ext.woff2 differ
diff --git a/site/assets/fonts/jetbrains-mono-normal-latin.woff2 b/site/assets/fonts/jetbrains-mono-normal-latin.woff2
new file mode 100644
index 000000000..4d09cda4a
Binary files /dev/null and b/site/assets/fonts/jetbrains-mono-normal-latin.woff2 differ
diff --git a/site/assets/fonts/noto-sans-math-normal-subset.woff2 b/site/assets/fonts/noto-sans-math-normal-subset.woff2
new file mode 100644
index 000000000..2d247d69f
Binary files /dev/null and b/site/assets/fonts/noto-sans-math-normal-subset.woff2 differ
diff --git a/site/assets/fonts/noto-sans-mono-normal-subset.woff2 b/site/assets/fonts/noto-sans-mono-normal-subset.woff2
new file mode 100644
index 000000000..94411ec60
Binary files /dev/null and b/site/assets/fonts/noto-sans-mono-normal-subset.woff2 differ
diff --git a/site/assets/og.png b/site/assets/og.png
new file mode 100644
index 000000000..0c325d537
Binary files /dev/null and b/site/assets/og.png differ
diff --git a/site/index.html b/site/index.html
new file mode 100644
index 000000000..71314b2a7
--- /dev/null
+++ b/site/index.html
@@ -0,0 +1,1680 @@
+
+
+
An automata-based C++ tool for quantum program verification.
+
+
+
AutoQ verifies the partial correctness of quantum programs. You state a precondition and a postcondition as sets of pure quantum states and give the program in OpenQASM. AutoQ represents each set as a tree automaton, carries it through the program gate by gate, and checks that every resulting state lies in the postcondition, up to a nonzero complex factor.
+ {P}
+
+ Ppreconditiona set of pure quantum states, written in .hsl or .lsta
+
+
+ C
+
+ Cprograma quantum program in a subset of OpenQASM 2.0 or 3.0
+
+
+ {Q}
+
+ Qpostconditionthe set that must contain every result, up to scaling
+
+ (1)
+
+
+
+
+
+
+
+
+
+
+
1What AutoQ checks
+
+
+
+
A Hoare triple {P} C {Q} is a claim about a program C: run it from a state allowed by the precondition P, and if it terminates, it ends in a state allowed by the postcondition Q. This is partial correctness, and AutoQ checks claims of this kind for quantum programs, up to scaling.
+
In AutoQ, P and Q each describe a set of pure quantum states rather than a single state. AutoQ starts from the whole set ℒ(P), computes how it is transformed immediately after each gate, and hands the result to the next gate. When the program ends, it checks that ℒ(Q) contains the final set C(ℒ(P)), up to scaling:
+
+ C(ℒ(P)) ⊆uts ℒ(Q)
+ (2)
+
+
That is, for every state |s⟩ ∈ C(ℒ(P)) there is a nonzero complex number c ∈ ℂ∖{0} with c|s⟩ ∈ ℒ(Q). A postcondition can therefore leave out normalization factors such as 1/√2; the worked example below relies on exactly that.
+
+
+
+
+
Sets of states as tree automata
+
+
+
AutoQ represents a set of states with a tree automaton. A state becomes a tree with one level per qubit, and each leaf stores one amplitude: in Figure 1 the leaf 000 stores the amplitude of |000⟩, 001 that of |001⟩, and so on. One automaton accepts many such trees, so it can stand for a whole set of states.
+
AutoQ 2.0 uses level-synchronized tree automata, in which each transition carries a set of choices. It also reorders qubits according to the precondition, postcondition and loop invariants, to keep the automata it builds small.
+
+
+
+
+
+
+ Figure 1. A 3-qubit state as a tree, one level per qubit. The leaf 000 stores the amplitude of |000⟩, and so on. Redrawn from docs/internal_structure.md.
+
+
+
+
+
+
+
+
2A worked example
+
+
+
+
This two-qubit example is adapted from the README. The precondition holds two states, and the program applies three gates. Each step shows the set of states after one more gate, the tree of each state, and the output of autoq ex on the program up to that point.
X flips the left bit, so in every tree the two halves under the root swap. The equal superposition maps onto itself, which is why its tree and its line of output do not change.
$ autoq ver pre.hsl circuit.qasm post_Q1.hsl
+The quantum program has [2] qubits and [3] gates. The verification process [OK] in [0.2s] with [77MB] memory usage.
+
+
The same two states without the 1/√2 factors. They match up to scaling, so the check passes.
+
+
+
Postcondition Q2 fails
+
+ post_Q2.hsl
+
Extended Dirac
+{|10> - |11>, |10> - |00>}
+
+
+
$ autoq ver pre.hsl circuit.qasm post_Q2.hsl
+The quantum program has [2] qubits and [3] gates. The verification process [failed] in [0.1s] with [77MB] memory usage.
+
+
One sign is flipped. The state |10⟩/√2 + |00⟩/√2 is in C(ℒ(P)), but no nonzero factor turns it into a state of ℒ(Q2).
+
+
+
+
+
+
+
+
+
+
+
+
3Get started
+
+
+
To try AutoQ without installing anything, open the playground: it runs the same tool in your browser, compiled to WebAssembly, with the examples from this page ready to run.
+
To install it, AutoQ builds from source on Linux (Ubuntu or Debian), macOS and WSL2. Four steps take you from a fresh clone to a verified program.
On Ubuntu and Debian, including under WSL2, the script installs g++, make, cmake, libboost-filesystem-dev, libboost-test-dev and libantlr4-runtime-dev with apt, so run it with sudo. On macOS, run it without sudo: it uses Homebrew to install gcc, make, cmake, boost and antlr4-cpp-runtime.
+
+
+
Build and test
+
+ Build and test
+
make
+make test
+
+
make compiles AutoQ with optimizations, and make test runs the unit tests. The binary is build/cli/autoq. For a debug build, run make debug instead of make.
+
+
+
Verify a program
+
ver is the mode used most often in the AutoQ papers. It takes a precondition, a circuit and a postcondition. Here it checks the README’s example, a Grover’s search benchmark on five qubits.
+
+ Verify the example
+
$ ./build/cli/autoq ver \
+ benchmarks/all/Grover/03/pre.hsl \
+ benchmarks/all/Grover/03/circuit.qasm \
+ benchmarks/all/Grover/03/post.hslThe quantum program has [5] qubits and [52] gates. The verification process [OK] in [0.1s] with [77MB] memory usage.
+
+
Times and memory figures in the outputs on this page come from one machine and will vary on yours.
The demo folder has more small examples, including Bernstein–Vazirani and a Grover iteration.
+
+
+
+
+
+
Commands
+
+
ex
autoq ex [OPTIONS] pre.hsl circuit.qasm Execute a quantum circuit with a given precondition. Option: --loopsum
+
ver
autoq ver [OPTIONS] pre.hsl circuit.qasm post.hsl Verify the execution result against a given postcondition. Options: --loopsum, -l, --latex
+
eq
autoq eq [OPTIONS] circuit1.qasm circuit2.qasm Check equivalence of two given quantum circuits. Option: --loopsum
+
print
autoq print [OPTIONS] states.hsl Print the set of quantum states.
+
+
--loopsum summarizes loops using symbolic execution. -l, --latex on ver prints the statistics for tables in LaTeX. autoq -v prints the full Git commit hash.
+
+
+
+
+
+
+
4From circuits to programs
+
+
+
AutoQ 2.0 goes beyond straight-line circuits. It verifies programs that measure, branch and loop, and it accepts symbolic amplitudes in specifications. AutoQ can also check whether two circuits are equivalent.
+
+
+
+
4.1 Symbolic amplitudes
+
+
+
An amplitude may use names that are not declared in the Constants section. AutoQ treats them as free symbolic variables, which the optional Constraints section can restrict. The precondition below, {x|0⟩ + y|1⟩}, therefore stands for every state of that form, and the postcondition requires each amplitude to come back unchanged.
Applying H twice passes. In the H2BugSym benchmark the second H is replaced by Y, and verification fails.
+
+
+ Gates of H2Sym/circuit.qasm, and the run
+
h qubits[0];
+h qubits[0];
+$ autoq ver pre.hsl circuit.qasm post.hsl
+The quantum program has [1] qubits and [2] gates. The verification process [OK] in [0.2s] with [85MB] memory usage.
+
+
+ Gates of H2BugSym/circuit.qasm, and the run
+
h qubits[0];
+y qubits[0];
+$ autoq ver pre.hsl circuit.qasm post.hsl
+The quantum program has [1] qubits and [2] gates. The verification process [failed] in [0.2s] with [86MB] memory usage.
+
+
+
+
+
+
+
4.2 Measurement, branching and loops
+
+
+
A program can measure a qubit into a classical bit and then branch on it with if and else, or loop on it with while. The if block runs on the states where the outcome is 1, the else block on those where it is 0, and AutoQ joins the two results. Both if (!c) and while (!c) are allowed, and else is optional.
+
A while loop needs a measurement just before the loop and at the end of its body, plus a loop invariant: a set of states in its own .hsl file, named in a comment on the while line. AutoQ checks that the states reaching the loop lie in the invariant, and that one pass of the body maps the invariant’s continuing states back into it. It then carries on with the states that leave the loop.
$ autoq ver pre.hsl circuit.qasm post.hsl
+The quantum program has [2] qubits and [6] gates. The verification process [OK] in [0.2s] with [84MB] memory usage.
+
+
+
+
+
+
4.3 Loop summarization
+
+
+
A loop for int i in [x:y] { C } runs its body C exactly y − x + 1 times. By default AutoQ applies the body’s gates one iteration after another. With --loopsum on ex or ver, AutoQ applies its loop summarization algorithm, which uses symbolic execution, to the loop’s body.
...
+qreg qb[1]; // quantum register
+...
+for int i in [1:2] {
+ h qb[0];
+ t qb[0];
+}
+...
+
+
+
+
+
4.4 Circuit equivalence
+
+
+
autoq eq checks whether two circuits are equal. A CX gate equals a CZ placed between two H gates on the target qubit; reversing control and target gives a different circuit.
$ autoq eq a.qasm b.qasm
+The two quantum programs are verified to be [equal] in [0.0s] with [7MB] memory usage.
+$ autoq eq a.qasm c.qasm # c.qasm: cx q[1], q[0];
+The two quantum programs are verified to be [unequal] in [0.0s] with [7MB] memory usage.
+
+
+
+
+
+
4.5 Gate set
+
+
+
AutoQ documents the fourteen gates below, written in OpenQASM with the spelling shown under each. Gates the parser does not recognise, such as u3 or cy, stop the run with an unsupported gate error.
+
+
+
+
Xx
+
Yy
+
Zz
+
Hh
+
Tt
+
T†tdg
+
Ss
+
S†sdg
+
Rx(π/2)rx(pi/2)
+
Ry(π/2)ry(pi/2)
+
CXcx
+
CZcz
+
CCXccx
+
SWAPswap
+
+
+
+
+
+
+
+
5Writing specifications
+
+
+
Preconditions, postconditions and loop invariants are all sets of quantum states. Specifications are written in .hsl or .lsta; programs in .qasm.
+
+
.hsl
A high-level specification language that extends Dirac notation to describe sets of quantum states. A file has a Constants section (optional), an Extended Dirac section, and a Constraints section (optional), in that order.
OpenQASM 2.0 or 3.0, with very limited syntax: a single quantum register, classical bits used only right before control flow, the fourteen gates above, if/else, while and for.
A set of states written directly as a level-synchronized tree automaton. It keeps Constants and Constraints and replaces Extended Dirac with Root States and Transitions.
$ autoq ver pre.hsl circuit.qasm post.hsl
+The quantum program has [2] qubits and [2] gates. The verification process [OK] in [0.1s] with [77MB] memory usage.
+
+
+
+
+
+
+
+
+
+ Table 1. Extended Dirac notation at a glance
+
+
+
Extended Dirac notation
+
Notation
Meaning
ASCII
+
+
S ∪ T
union of two sets of states
+
S ⊗ T
tensor product of two sets
S * T
+
S ^ n
tensor power
+
|i⟩, |1i′⟩
binary-string variable (lowercase), and its complement
|1i'>
+
∑ |i|=4, i≠0101 |i⟩
sum over strings that meet the constraints
Σ, !=
+
{ … : |s|=4, s≠0101 }
set-builder notation with constraints
!=
+
= ≠ < ≤ > ≥ ¬ ∧ ∨
operators in the Constraints section, one conjunct per line
!= <= >= ! && ||
+
+
+
+
Kets can be closed with ⟩ or >. Constants may use real(c), imag(c), eipi(r), ei2pi(r), sqrt2, nonnegative integers and + - * / ^.
+
+
+
+
+
+
+
+
+
+
6Papers
+
+
+
Please cite the following papers if you use this tool for your research.
@article{10.1145/3704868,
+ title = {Verifying Quantum Circuits with Level-Synchronized Tree Automata},
+ author = {Abdulla, Parosh Aziz and Chen, Yo-Ga and Chen, Yu-Fang and Hol\'{\i}k, Luk\'{a}\v{s} and Leng\'{a}l, Ond\v{r}ej and Lin, Jyun-Ao and Lo, Fang-Yi and Tsai, Wei-Lun},
+ journal = {Proceedings of the ACM on Programming Languages},
+ volume = {9},
+ number = {POPL},
+ year = {2025},
+ pages = {923--953},
+ doi = {10.1145/3704868}
+}
@InProceedings{10.1007/978-3-031-90660-2_5,
+ author = {Chen, Yu-Fang and Chung, Kai-Min and Hsieh, Min-Hsiu and Huang, Wei-Jia and Leng{\'a}l, Ond{\v{r}}ej and Lin, Jyun-Ao and Tsai, Wei-Lun},
+ booktitle = {International Conference on Tools and Algorithms for the Construction and Analysis of Systems (TACAS)},
+ title = {AutoQ 2.0: From Verification of Quantum Circuits to Verification of Quantum Programs},
+ year = {2025},
+ pages = {87--108},
+ doi = {10.1007/978-3-031-90660-2_5}
+}
+
+
+
+
+
+
+
The benchmarks folder holds all the files used to produce the experimental results.
+
+
+
+
+
+
+
+
+
7Learn more, ask questions
+
+
+
Watch
+
The introductory video shows more examples of how to use AutoQ.
Run AutoQ in your browser. This is the command-line tool itself, compiled to WebAssembly: it reads the same .hsl and OpenQASM files and prints the same output. Everything runs on your machine; nothing is uploaded.
+
Loading AutoQ…
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Output
+
+
+
+
+
+
+
+
+
Notes
+
+
ver checks the circuit against the postcondition and prints [OK] or [failed]. ex prints the set of states after the circuit. eq compares the circuits in a.qasm and b.qasm and prints [equal] if they implement the same unitary up to a global phase; it reads the qubit count from an OpenQASM 2.0 qreg declaration. eq has its own files and examples; ver and ex share theirs, and edits are kept when you switch.
+
A while loop names its invariant file in a trailing comment, as in the While loop example. Every file in the tabs is available to the run under its tab name.
+
The first run downloads the WebAssembly module (it includes the Z3 solver). Later runs reuse it.
+
Runs use a single thread and the memory your browser allows a page, so the larger benchmarks from the papers may be slow or run out of memory here. Use the native build for those.
+
One difference from the native build: WebAssembly has no floating-point traps, so an arithmetic error that stops the native tool with SIGFPE continues here.
+
The file formats are described in the .hsl and OpenQASM documentation.