Z3.wasm
WASM builds of the Z3 SMT solver
Install / Use
/learn @cpitclaudel/Z3.wasmREADME
=============
z3.wasm
This repo contains a build script to compile Z3 <https://github.com/Z3Prover/z3/>_ to WebAssembly using emscripten <https://github.com/kripken/emscripten/>. To make things more reproducible, the build script may be run in a Vagrant <https://www.vagrantup.com/> VM.
Loading Z3 is fairly slow (~15 seconds on Chrome, though less than 1 second on Firefox), but verification typically is within a factor 2 to 5 of native performance.
Pre-build archives are available at https://github.com/cpitclaudel/z3.wasm/releases. Demo at https://people.csail.mit.edu/cpitcla/z3.wasm/z3.html.
Building
In a VM
Install Vagrant <https://www.vagrantup.com/>_, then run this::
vagrant up vagrant ssh VAGRANT=true /vagrant/z3.sh
The first build can take up to two hours (emscripten may require a custom build of LLVM, Z3 is large, and all of this is running in a VM). The output (z3w.js, z3w.wasm, z3smt2w.js, and z3smt2w.wasm) is written to build/z3/.
Some Vagrant configurations can cause clang to crash or Vagrant to hang. Building on a physical machine is the most reliable workaround.
Natively
On Debian/Ubuntu systems, you may prefer to build natively, which will be much faster. In that case, just run ./z3.sh, which will place all outputs in build/.
Using the generated code
The build script produces two artefacts: a copy of the full Z3 command line application (z3w.js, z3w.wasm), and a Javascript version of a small SMT2 REPL-style API, built by linking z3smt2.c with libz3.
z3w.js
There is a small example script using nodejs for demonstration purposes in the repo::
$ nodejs z3test.js /nodefs/test.smt2 sat (model (define-fun y () Int 3) (define-fun x () Int 2) (define-fun z () Int 1) (define-fun g ((x!0 Int) (x!1 Int)) Int (ite (and (= x!0 2) (= x!1 2)) 0 0)) (define-fun f ((x!0 Int)) Int (ite (= x!0 2) (- 1) (ite (= x!0 3) 1 (- 1)))) ) unsat (error "line 14 column 10: model is not available") unsat
From a webpage the process is roughly the same: write Z3's input to a file using emscripten's virtual file system, and use callMain(args) to run Z3. To capture Z3's output, you can pass a custom print function to the emscripten module upon initialization.
This is all demoed in html/z3.html (that example also uses a WebWorker to run Z3, keeping the page responsive while it runs). Try it like this::
cp build/z3/z3w.js build/z3/z3w.wasm ./html python3 -m http.server
Open your browser to http://localhost:8000/html/z3.html
z3smt2w.js
This script exposes a small API useful for verifiers (like F* or Dafny) that interact with Z3 on through pipes. It exposes the following functions::
// Create a fresh SMT2 context Z3_context smt2Init()
// Globally set option to value.
void smt2SetParam(const char* option, const char* value)
// Send query to ctx and fetch the response as a string.
const char* smt2Ask(Z3_context ctx, const char* query)
// Release the resources used by ctx.
void smt2Destroy(Z3_context ctx)
There is a small example script using nodejs for demonstration purposes in the repo::
$ nodejs ./z3smt2test.js sat (model (define-fun y () Int 4) (define-fun x () Int 2) (define-fun z () Int 0) (define-fun g ((x!0 Int) (x!1 Int)) Int (ite (and (= x!0 2) (= x!1 2)) 0 0)) (define-fun f ((x!0 Int)) Int (ite (= x!0 2) (- 1) (ite (= x!0 4) 1 (- 1)))) ) unsat (error "line 1 column 11: model is not available") unsat
Check the source code of F*.js for an example of how to use this in a larger application.
Known issues, tips
Chrome precompiles WebAssembly programs before running them — this makes startup slow, though verification after that is fast. The recommendation is to cache compiled modules, but Chrome doesn't (2018-03) allow that yet.
Firefox is much better at this, though the code eventually does run a slower.
Compression
The limited z3smt2.wasm is a bit smaller than the full Z3: use that if you can.
On Apache servers, use the following to compress WASM files (gzipping saves about 75%)::
AddType application/wasm .wasm AddOutputFilterByType DEFLATE application/wasm
Related Skills
node-connect
349.7kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.7kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.7kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.7kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
