On this page:
1.1 This reference and This is Boogie 2
1.2 What the paper describes that no longer exists
1.3 What has been added since 2008
1.4 How this reference is organised
1.5 Notation

1 Introduction🔗

1.1 This reference and This is Boogie 2🔗

The canonical description of the language is K. Rustan M. Leino’s This is Boogie 2 (manuscript KRML 178, working draft of 24 June 2008). It remains the best account of why Boogie is shaped the way it is: the trace semantics, the design of the type system, the reasoning behind where clauses, free specifications and the caller/callee split. This reference does not replace it and does not try to re-derive it. Read the paper for the design; read this for what the tool does.

The paper is now old enough that a reader who follows it literally will write programs that do not parse. Three of its sections describe features that have since been removed, and a good deal of the language has been added since. The rule adopted throughout this reference is simple:

The implementation is the authority. The grammar file decides syntax, the C# source decides behaviour, and the paper decides design intent. Where the paper and the tool disagree, the tool wins and the difference is stated explicitly.

Every chapter states its divergences explicitly, in almost every case in a closing section called Divergences from This is Boogie 2. (The exception is Command-line reference, which the paper does not touch at all; it says so in its own opening.)

1.2 What the paper describes that no longer exists🔗

Two smaller drifts are worth knowing before reading the paper’s appendix. Its reserved-word list has 38 entries and includes bv0, bv1, complete and finite; the scanner’s list has 68 and includes none of those. And its account of identifiers permits non-English Unicode letters; the implementation’s letter class is exactly the 52 ASCII letters.

1.3 What has been added since 2008🔗

Section 11 of the paper says that “the Boogie language does not assign any formal meaning to the attributes”. That is the statement in it which has aged worst. The tool now reads more than seventy distinct attribute names, and several of them — {:verify}, {:inline}, {:define}, {:ignore}, {:subsumption}, {:verified_under}, {:checksum} change what is proved. The paper’s own proposed spellings have drifted too: {:errorMessage} is implemented as {:msg}, and {:bvBuiltin "bvadd 8"} is implemented as {:bvbuiltin "bvadd"} all lower case, no width. Since an unrecognised attribute name is silently ignored, writing the paper’s spelling produces no diagnostic at all, just a function that stays uninterpreted.

1.4 How this reference is organised🔗

The chapters run roughly bottom-up. Lexical structure through Statements and control flow describe the core language, in the order tokens, types, expressions, declarations, procedures, statements. Bitvectors, floating point and rounding modes, Strings and regular expressions and Algebraic datatypes cover the type families that need more than a paragraph. The standard library describes what /lib: gives you, Attributes is the attribute index, Civl: concurrency and refinement is the concurrency layer, Advanced topics and tool internals is what happens between the program and the solver, and Command-line reference documents every option the tool accepts.

A construct is documented in one place and cross-referenced from the others. Where two chapters could plausibly own a topic, the split is between surface and mechanism: Attributes gives an attribute’s argument shape and where it may be written, while the chapter that owns the feature explains what it does; Command-line reference gives an option’s syntax and default, while the chapter that owns the pass explains its effect.

1.5 Notation🔗

Grammar. Productions are quoted verbatim from Source/Core/BoogiePL.atg, in Coco/R’s EBNF, with the semantic actions elided:

IdsTypeWhere<. bool allowWhereClauses, string context, ... .>

= Idents ":" Type

  [ "where" Expression ]

  .

Braces { x } mean zero or more repetitions, brackets [ x ] mean optional, | separates alternatives, and quoted strings are terminals. The angle-bracket groups <. ... .> and <...> are Coco/R’s parameter lists, not part of the language. Anything inside a grammar block is what the grammar file says, including its comments and its occasional spelling mistakes. If a construct does not appear in BoogiePL.atg, it does not exist.

Listings. Boogie source appears like this:

procedure Abs(x: int) returns (r: int)

  ensures 0 <= r;

{

  if (x < 0) { r := -x; } else { r := x; }

}

Commands and output. A command line, and the output it produced:

boogie cli-small.bpl

Boogie program verifier finished with 1 verified, 0 errors

Nothing in an output block is reconstructed from memory. Where a block is an excerpt — of a prover log, of a /print dump, of a long /trace run — it says so at that point. Timings, solver resource counts, counterexample model values and the numeric suffixes in monomorphised names vary between runs and between builds; those are noted where they appear.

Failing examples are shown with the diagnostics the tool actually produces.

Spelling. British spelling throughout, except in quoted source, quoted output, option names and attribute names, which use whatever the tool uses.

Environment. Boogie 3.5.7.0 with Z3 5.0.0 on Linux. A few results were cross-checked against cvc5 1.3.3, which is stated where it matters — notably in Portability to other solvers, since Boogie writes the regular-expression sort as Z3’s RegEx rather than SMT-LIB 2.6’s RegLan.