Deploy Boogie to Europe β K. Rustan M. Leino πΊπΈ + Microsoft Research (2005), the Intermediate Verification Language that Powers Dafny, Chalice, and Viper Carbon β the Backend of the EU Formal Verification Stack, on EU Infrastructure in 2026
Behind every verified Viper program, every checked Dafny function, every Chalice permission proof β there is one tool doing the hardest work.
Boogie is an intermediate verification language (IVL) and verification condition generator developed primarily by K. Rustan M. Leino πΊπΈ (Microsoft Research Redmond), Mike Barnett (Microsoft Research), and Bart Jacobs π§πͺ (then Microsoft Research, later KU Leuven), first published at the FMCO 2005 conference and refined in Leino's 2008 technical report "This is Boogie 2." The rewrite to Boogie 2 established the design that all modern dependents use: a language clean enough to be generated by automated translators, expressive enough to encode the full range of object-oriented heap reasoning, and connected tightly enough to Z3 via weakest precondition calculus to discharge complex verification conditions in practice.
Boogie is not a language you write programs in. It is a language that other tools write into β a shared substrate for verification condition generation that allows each frontend to focus on its language-specific translation while delegating the mathematical heavy lifting to a single proven engine. This is precisely the architecture that scaled: Dafny generates Boogie. Chalice generates Boogie. Viper's Carbon backend generates Boogie. Any new verifier built on this lineage inherits a decade of engineering in SMT encoding, loop invariant handling, and quantifier trigger selection.
Why an Intermediate Verification Language?
The alternative to an IVL is a direct translation: your source language β SMT assertions. This works for small tools but breaks at scale. Direct encoders must re-implement loop invariant checking, frame conditions, two-state reasoning, and heap encoding independently for every new source language. Each re-implementation introduces bugs, diverges from others, and cannot share infrastructure.
Boogie solves this with a single, carefully designed middle layer. Frontends translate into BoogiePL. Boogie applies weakest precondition calculus to generate verification conditions. Z3 discharges them. The verification logic β how loops are handled, how frames are checked, how quantifiers are triggered β lives in one place, maintained by one team, tested by thousands of programs across all dependents simultaneously.
The analogy is LLVM for compilers: language-specific frontends generate LLVM IR; the backend handles optimisation and code generation. Boogie is the LLVM of formal verification β an IR designed for correctness proofs rather than executable code.
BoogiePL: The Language
BoogiePL is a simple, untyped (with polymorphism) imperative language. A Boogie program consists of:
Types and the heap model:
// Reference type: all objects are Refs
type Ref;
const null: Ref;
// Fields are typed by what they store
type Field alpha;
// The heap is a polymorphic map
var Heap: <alpha>[Ref, Field alpha]alpha;
The heap type <alpha>[Ref, Field alpha]alpha is the central innovation. The heap is a polymorphic array: given a reference this: Ref and a field balance: Field int, Heap[this, balance] retrieves the integer stored at this.balance. A field update Heap[this, balance] := v is a functional map update β the new heap equals the old heap everywhere except at (this, balance).
This encoding is deliberately simple. It has no aliasing structure, no ownership, no separation. Those are supplied by the frontend. Chalice adds permission variables tracking ownership of each (ref, field) pair. Viper adds acc(x.f, p) inhale/exhale operations that manipulate permission masks layered on top of the heap map. Boogie itself just handles the heap as a mathematical map and lets Z3 reason about equality and updates.
Procedures:
procedure BankAccount_Deposit(this: Ref, amount: int)
requires amount >= 0;
requires Heap[this, balance] >= 0;
modifies Heap;
ensures Heap[this, balance] == old(Heap[this, balance]) + amount;
{
Heap[this, balance] := Heap[this, balance] + amount;
}
requires: precondition β must hold at call siteensures: postcondition β proved to hold at procedure exitmodifies Heap: frame condition β this procedure only modifies the heap (not other globals)old(e): value of expressionein the pre-state at procedure entryfree requires: assumed but not checked (used for invariants callee need not re-prove)
Loop invariants:
var sum: int;
var i: int;
sum := 0; i := 0;
while (i < n)
invariant 0 <= i && i <= n;
invariant sum == i * (i - 1) / 2;
{
sum := sum + i;
i := i + 1;
}
assert sum == n * (n - 1) / 2;
Loop invariants are checked at entry and after each iteration. Boogie cuts the loop: it verifies that (1) the invariant holds initially, (2) if the invariant holds before the body, it holds after, and (3) after the loop exits, the invariant and the negated guard are sufficient to prove subsequent assertions. This transforms a loop verification problem into two straight-line VC queries to Z3.
Havoc and assume:
var x: int;
havoc x; // x is now non-deterministic
assume x > 0; // constrain: only consider executions where x > 0
assert x * x > 0; // provable under the assumption
havoc models unverified values β unknown return values, unmodelled environment. assume constrains the non-deterministic choice. Together they encode procedure calls at call sites: havoc the return value and any modified globals, assume the postcondition, then continue verifying the caller.
Functions and axioms:
function min(a: int, b: int): int;
axiom (forall a: int, b: int ::
(a <= b ==> min(a, b) == a) &&
(a > b ==> min(a, b) == b));
Functions are uninterpreted by default; axioms give them meaning in the SMT theory. This is used to encode mathematical abstractions β sequences, sets, multisets β that frontends need for specification but that Boogie itself does not provide as built-ins.
Quantifier triggers:
axiom (forall<alpha> h: HeapType, o: ref, f: Field alpha ::
{ h[o, f] } // trigger: whenever Z3 encounters h[o,f], instantiate this axiom
IsHeapAnchor(h) ==> TypeOfRef(h, o, f) == typeof(f));
The { ... } annotation is a trigger β a hint to Z3's quantifier instantiation engine specifying which terms should cause the forall to be instantiated. Well-chosen triggers are the difference between a verification that completes in milliseconds and one that times out. Boogie frontends invest significant engineering in trigger selection; this knowledge is shared across all tools that generate Boogie.
The Weakest Precondition Pipeline
Boogie's core algorithm transforms a BoogiePL procedure into a single logical formula β the verification condition β that is satisfiable if and only if the procedure can violate one of its postconditions or assertions. Z3 then checks satisfiability: if unsatisfiable, the procedure is verified.
The transformation follows weakest precondition (WP) calculus:
WP[skip, Q] = Q
WP[x := e, Q] = Q[x/e]
WP[assert P, Q] = P β§ Q
WP[assume P, Q] = P β Q
WP[havoc x, Q] = βx. Q
WP[S1; S2, Q] = WP[S1, WP[S2, Q]]
WP[if P then S1 else S2] = (P β WP[S1,Q]) β§ (Β¬P β WP[S2,Q])
For the requires r; ensures e contract, Boogie generates:
r β WP[body, e]
This is discharged by Z3 as an SMT query. If Z3 finds a model (an assignment to all free variables) that makes the formula false β i.e., a counterexample where the precondition holds but the body can reach a state violating the postcondition β verification fails and the counterexample is reported.
Loops are handled by the cut-point method: replace each loop with havoc of all modified variables, assume of the invariant, execute one body iteration, assert the invariant holds, and assume false to stop (the post-loop case is handled by a parallel path where the guard is false and the invariant holds).
Boogie in the EU Verification Ecosystem
The EU formal verification cluster depends on Boogie in two ways: through Viper Carbon and through the Chalice β Boogie lineage.
Viper Carbon (ETH Zurich π¨π)
Viper, the permission-based IVL developed by Peter MΓΌller π¨π, Malte Schwerhoff π©πͺ, and Alexander Summers π¨π at ETH Zurich, has two verification backends:
- Silicon: symbolic execution engine with a custom permission heap, discharges to Z3 directly
- Carbon: VC generator that translates Viper Silver to BoogiePL, then calls Boogie β Z3
When a Prusti (Rust), Gobra (Go), or Nagini (Python) program is verified using --backend Carbon, the verification path is:
Source program
β Language-specific frontend (Prusti/Gobra/Nagini)
β Viper Silver IL
β Viper Carbon
β BoogiePL
β Boogie (WP calculus)
β SMT-LIB2
β Z3
β Verified / Counterexample
Carbon encodes Viper's permission model β acc(x.f, p) fractional permissions, inhale/exhale semantics, predicate fold/unfold β into Boogie state variables and assertions. The permission mask becomes a Boogie variable Mask: [Ref, Field]Perm; each inhale acc(x.f, p) becomes an update to Mask[x, f]; each assert on acc(x.f, p) becomes a check that Mask[x, f] >= p.
This is precisely the model Chalice used. The Chalice β Boogie encoding, developed at ETH Zurich, became the reference design for Carbon.
Bart Jacobs and the VeriFast Connection
Bart Jacobs π§πͺ (KU Leuven) co-authored the original Boogie paper (FMCO 2005) while at Microsoft Research. His work on Boogie's heap encoding β particularly the polymorphic [Ref, Field alpha]alpha model β influenced the design of separation logic tools he later developed at KU Leuven. VeriFast, which Jacobs co-created in 2008, uses symbolic execution over separation logic rather than WP calculus over Boogie, but the conceptual debt to Boogie's heap model is clear: both tools treat the heap as a mathematical map and use permission-style annotations to carve it into disjoint regions.
The EU cluster of formal verification tools β Boogie β Chalice β Viper β Prusti/Gobra/Nagini (ETH Zurich π¨π), and Boogie β VeriFast (KU Leuven π§πͺ, via Jacobs) β traces a direct lineage back to one engineering team at Microsoft Research Redmond and one core architectural decision: the polymorphic heap map.
Dafny and Industrial EU Deployment
Dafny, Leino's high-level verified programming language (2009), uses Boogie as its sole backend. Dafny β Boogie β Z3 is the production pipeline for:
- Amazon AWS: formal verification of S3, Glacier, EC2, and distributed protocol implementations (documented in CACM 2022)
- EU academic groups: TU Delft π³π± (distributed systems), TU Munich π©πͺ (concurrent algorithms), EPFL π¨π (systems software)
- Microsoft Azure: internal protocol verification
The EU significance: Dafny programs deployed on EU infrastructure β verified distributed protocols, verified data pipelines β carry Boogie-generated proofs. Those proofs are EU AI Act Art. 9 evidence by construction.
EU Regulatory Alignment
EU AI Act Art. 9 (High-Risk System Risk Management): Boogie's postcondition verification provides the strongest available form of functional correctness evidence. A Boogie-verified procedure has been mathematically proved to satisfy its postcondition for all inputs satisfying its precondition β not a probabilistic argument, not a test coverage number, but a formal proof. For high-risk Annex III AI systems, Art. 9 requires "appropriate risk management measures" including technical robustness. Boogie-discharged Dafny or Viper proofs constitute machine-checked evidence meeting this standard.
EU AI Act Art. 10 (Data Governance for Training Data): Data ingestion pipelines that sort, deduplicate, and normalise training data can be specified in Dafny (via Boogie) with loop invariants proving data integrity at each pipeline stage: invariant forall i, j :: 0 <= i < j < processed ==> data[i].timestamp <= data[j].timestamp. The Boogie VC for this invariant, discharged by Z3, provides Art. 10 documentation that the data ordering property is preserved throughout processing β not just spot-checked.
GDPR Art. 25 (Data Protection by Design): Boogie's modifies clause is a formal frame condition: a procedure with modifies Heap cannot read or write global variables outside the heap; a procedure with modifies {} is a pure function. Data minimisation can be encoded as: access to personalData fields is only via procedures with explicit modifies declarations. Any Boogie-verified program where personal data fields appear only in procedures with documented modifies clauses provides structural Art. 25 evidence.
Cyber Resilience Act (CRA, 2027): The CRA Article 13 requires manufacturers of digital products to implement vulnerability handling and testing. Dafny programs targeting EU embedded and IoT systems (via compilation to C) carry Boogie-discharged proofs of memory safety properties and functional invariants β directly applicable as CRA technical documentation.
IEC 61508 / EN 50128 (Safety-Integrity Level 3/4): Boogie-generated proofs are acceptable formal verification evidence for IEC 61508 SIL 3/4 and EN 50128 SIL 4 railway software. The Boogie pipeline (source β BoogiePL β WP β SMT β Z3) is a well-defined, auditable transformation chain with no unverified steps between the specification language and the SMT solver.
Deploy Boogie on EU Infrastructure with sota.io
Boogie is distributed as a .NET tool via NuGet and as a standalone binary via GitHub releases:
# Install via .NET tool
dotnet tool install --global boogie
# Verify installation
boogie --version
# Run a BoogiePL file
boogie AccountExample.bpl
# With explicit Z3 path
boogie /z3exe:/usr/bin/z3 AccountExample.bpl
# Install Dafny (uses Boogie internally)
dotnet tool install --global dafny
# Verify a Dafny file (Boogie is called automatically)
dafny verify BankAccount.dfy
A minimal BoogiePL program demonstrating the core features:
// Types
type Ref;
const null: Ref;
function {:builtin "MapConst"} MapConstBool(bool): [Ref]bool;
// Fields
const unique balance: Field int;
const unique owner: Field Ref;
// Heap
var Heap: <alpha>[Ref, Field alpha]alpha;
var alloc: [Ref]bool;
// Constructor
procedure Account_new(initial: int) returns (this: Ref)
requires initial >= 0;
modifies Heap, alloc;
ensures alloc[this] && !old(alloc)[this];
ensures Heap[this, balance] == initial;
{
havoc this;
assume !alloc[this] && this != null;
alloc[this] := true;
Heap[this, balance] := initial;
}
// Deposit
procedure Account_deposit(this: Ref, amount: int)
requires alloc[this];
requires amount >= 0;
requires Heap[this, balance] >= 0;
modifies Heap;
ensures Heap[this, balance] == old(Heap[this, balance]) + amount;
{
Heap[this, balance] := Heap[this, balance] + amount;
}
// Verified query
procedure Account_balance_nonneg(this: Ref)
requires alloc[this];
requires Heap[this, balance] >= 0;
ensures Heap[this, balance] >= 0;
{}
Run on sota.io β the EU-native PaaS on German infrastructure, GDPR-compliant by default:
# sota.io deploy
sota deploy --region eu-central
sota.io provides:
- EU data residency β Boogie verification artifacts, BoogiePL generated files, proof obligation results, and correctness certificates stay in Germany. No US Cloud Act exposure for source code or formal proofs.
- Managed PostgreSQL β store Boogie verification history, VC generation statistics, per-commit proof states, and compliance evidence for IEC 61508 / EU AI Act audits.
- Zero DevOps β push your Dafny/Boogie CI container and sota.io handles deployment, scaling, and database backups.
- GDPR compliance β source code and verification metadata processed in EU jurisdiction, never leaving European infrastructure.
Free tier available. No credit card required to start.
See Also
- Deploy Chalice to Europe β β Chalice (ETH Zurich π¨π, 2009) uses Boogie as its verification backend; the Chalice β Boogie encoding became the blueprint for Viper Carbon
- Deploy Viper to Europe β β Viper Carbon (ETH Zurich π¨π) translates Viper Silver to BoogiePL for VC generation
- Deploy Prusti to Europe β β Viper-based Rust verifier (ETH Zurich π¨π); with Carbon backend uses Boogie for VC generation
- Deploy Gobra to Europe β β Viper-based Go verifier (ETH Zurich π¨π); Carbon backend path goes through Boogie
- Deploy Nagini to Europe β β Viper-based Python verifier (ETH Zurich π¨π); Carbon backend uses Boogie for Z3 dispatch
- Deploy VeriFast to Europe β β VeriFast (KU Leuven π§πͺ) co-authored by Bart Jacobs, co-author of the original Boogie; shared intellectual lineage